@microi.net/cli 5.2.8 → 5.2.9

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 (23) hide show
  1. package/.codebuddy-plugin/marketplace.json +2 -2
  2. package/.codebuddy-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/.workbuddy-plugin/marketplace.json +2 -2
  5. package/.workbuddy-plugin/plugin.json +1 -1
  6. package/assets/build-meta.json +3 -3
  7. package/cordis.patch.yml +1 -1
  8. package/package.json +1 -1
  9. package/scripts/microi-skills.meta.json +196 -196
  10. package/skills/.microi-skills-version.json +2 -2
  11. package/skills/message-notification/SKILL.md +4 -0
  12. package/skills/message-notification/references/contracts.md +1 -0
  13. package/skills/microi-ai-app-auth.js +4 -3
  14. package/skills/microi-client-frontend/references/progressive-01-3-/345/212/250/346/200/201/346/214/211/351/222/256/347/263/273/347/273/237.md +1 -1
  15. package/skills/microi-client-frontend/references/progressive-02-8-/350/277/220/350/241/214/346/227/266/351/253/230/351/242/221/345/235/221/345/244/215/347/233/230.md +1 -1
  16. package/skills/microi-frontend-sdk/SKILL.md +1 -1
  17. package/skills/microi-mobile-app-quality/SKILL.md +1 -1
  18. package/skills/microi-system-delivery/references/progressive-02-/350/207/252/345/212/250/345/214/226/346/265/213/350/257/225/345/277/205/351/241/273/350/246/206/347/233/226/347/232/204/345/235/221.md +1 -1
  19. package/skills/microi-uniapp-frontend/SKILL.md +1 -1
  20. package/skills/microi.v8.js +75 -21
  21. package/skills/v8-file-upload/references/progressive-01-/345/205/254/346/234/211/346/241/266-vs-/347/247/201/346/234/211/346/241/266.md +1 -1
  22. package/skills/v8-file-upload/references/progressive-02-office-/346/226/207/344/273/266/345/234/250/347/272/277/347/274/226/350/276/221/347/211/210/346/234/254/345/217/267/350/247/204/345/210/231.md +1 -1
  23. package/skills/v8-utilities/references/platform-http-routes.md +1 -1
@@ -5,13 +5,13 @@
5
5
  "url": "https://microi.net"
6
6
  },
7
7
  "description": "Microi吾码官方 AI 插件市场",
8
- "version": "5.2.8",
8
+ "version": "5.2.9",
9
9
  "plugins": [
10
10
  {
11
11
  "name": "microi",
12
12
  "source": ".",
13
13
  "description": "Microi吾码 AI 开发插件:服务器连接、Skills、MCP、V8 全量同步与低代码交付",
14
- "version": "5.2.8",
14
+ "version": "5.2.9",
15
15
  "strict": true
16
16
  }
17
17
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "microi",
3
- "version": "5.2.8",
3
+ "version": "5.2.9",
4
4
  "description": "Microi吾码 AI 开发插件:服务器连接、Skills、MCP、V8 全量同步与低代码交付",
5
5
  "author": {
6
6
  "name": "Microi.Net",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "microi",
3
- "version": "5.2.8",
3
+ "version": "5.2.9",
4
4
  "description": "Microi吾码低代码平台的 Codex 开发插件,共享 VS Code/CLI 的连接、同步、MCP、V8 与交付能力。",
5
5
  "author": {
6
6
  "name": "Microi.Net",
@@ -5,13 +5,13 @@
5
5
  "url": "https://microi.net"
6
6
  },
7
7
  "description": "Microi吾码官方 AI 插件市场",
8
- "version": "5.2.8",
8
+ "version": "5.2.9",
9
9
  "plugins": [
10
10
  {
11
11
  "name": "microi",
12
12
  "source": ".",
13
13
  "description": "Microi吾码 AI 开发插件:服务器连接、Skills、MCP、V8 全量同步与低代码交付",
14
- "version": "5.2.8",
14
+ "version": "5.2.9",
15
15
  "strict": true
16
16
  }
17
17
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "microi",
3
- "version": "5.2.8",
3
+ "version": "5.2.9",
4
4
  "description": "Microi吾码 AI 开发插件:服务器连接、Skills、MCP、V8 全量同步与低代码交付",
5
5
  "author": {
6
6
  "name": "Microi.Net",
@@ -1,6 +1,6 @@
1
1
  {
2
- "builtAt": "2026-08-25T00:14:31.374Z",
3
- "version": "5.2.8",
2
+ "builtAt": "2026-08-25T02:18:24.149Z",
3
+ "version": "5.2.9",
4
4
  "sourceProducts": [
5
5
  "vscode-extension",
6
6
  "microi-cli",
@@ -13,6 +13,6 @@
13
13
  "cli": "19fa79f0727616fbaaa9cdffc2485dc58aede013931d3d5662baa36cdbf5eb07",
14
14
  "router": "ffc14787fc2d3d6173b7a779b77139b759eb1d482cea787f71283f4017a4e223",
15
15
  "broker": "caae2730cc411d11c20f33b367968f7538aae8f5b65a713fcc557deedaefcf70",
16
- "dshBundle": "fadc4ab2b7d4b512a19432fb7999085c9ef6f3262f8ce153583f0cc4127acfa4"
16
+ "dshBundle": "0c611e7277e2064009b4d789f721282bb1854054f535b164fb5e8d58f5294ebc"
17
17
  }
18
18
  }
package/cordis.patch.yml CHANGED
@@ -7,7 +7,7 @@
7
7
  serverName: microi
8
8
  transport: stdio
9
9
  command: !!js process.execPath
10
- args: ["-e","/*\n * DeepSeek Harness 通过 profile bundle 加载此 `node -e` 引导脚本。\n * DSH 不保证 MCP 子进程 cwd 位于 npm 包根,因此按 DSH_HOME/profile 定位\n * 当前版本的 @microi.net/cli,再复用 Codex 同源适配器与多连接路由器。\n */\nconst fs = require('node:fs');\nconst os = require('node:os');\nconst path = require('node:path');\nconst packageName = '@microi.net/cli';\nconst expectedVersion = '5.2.8';\n\nfunction readJson(filePath) {\n try { return JSON.parse(fs.readFileSync(filePath, 'utf8')); }\n catch { return undefined; }\n}\n\nfunction expandHome(value) {\n if (value === '~') return os.homedir();\n if (value.startsWith('~/') || value.startsWith('~\\\\')) return path.join(os.homedir(), value.slice(2));\n return value;\n}\n\nfunction validRoot(value) {\n const root = path.resolve(value);\n const pkg = readJson(path.join(root, 'package.json'));\n const patch = path.join(root, 'cordis.patch.yml');\n const adapter = path.join(root, 'scripts', 'mcp-codex-stdio-adapter.js');\n const router = path.join(root, 'scripts', 'microi-codex-router.js');\n if (pkg?.name !== packageName || pkg?.version !== expectedVersion) return undefined;\n if (pkg?.dsh?.bundle?.patch !== './cordis.patch.yml') return undefined;\n if (![patch, adapter, router].every(filePath => fs.existsSync(filePath))) return undefined;\n return { root: fs.realpathSync(root), adapter, router, modifiedAt: fs.statSync(router).mtimeMs };\n}\n\nfunction findPlugin() {\n const explicit = String(process.env.MICROI_DSH_PLUGIN_ROOT || '').trim();\n if (explicit) {\n const plugin = validRoot(explicit);\n if (!plugin) throw new Error(`MICROI_DSH_PLUGIN_ROOT 不是版本 ${expectedVersion} 的有效 Microi DSH bundle:${explicit}`);\n return plugin;\n }\n const configuredHome = String(process.env.DSH_HOME || '').trim();\n const dshHome = path.resolve(expandHome(configuredHome || path.join(os.homedir(), '.dsh')));\n const profilesRoot = path.join(dshHome, 'profiles');\n const candidates = [];\n if (fs.existsSync(profilesRoot)) {\n for (const entry of fs.readdirSync(profilesRoot, { withFileTypes: true })) {\n if (!entry.isDirectory() || entry.name === 'node_modules') continue;\n const root = path.join(profilesRoot, entry.name, 'node_modules', '@microi.net', 'cli');\n const plugin = validRoot(root);\n if (plugin) candidates.push(plugin);\n }\n }\n candidates.sort((left, right) => right.modifiedAt - left.modifiedAt);\n if (!candidates[0]) throw new Error(`未在 ${profilesRoot} 找到版本 ${expectedVersion} 的 ${packageName}`);\n return candidates[0];\n}\n\ntry {\n const plugin = findPlugin();\n process.env.MICROI_DSH_PLUGIN_ROOT = plugin.root;\n process.env.MICROI_CODEX_PLUGIN_ROOT = plugin.root;\n process.env.MICROI_TOOL_SOURCE = 'dsh';\n process.env.MICROI_TOOL_VERSION = expectedVersion;\n process.env.MICROI_WORKSPACE_ROOT = process.env.MICROI_WORKSPACE_ROOT || process.cwd();\n process.argv[2] = plugin.router;\n require(plugin.adapter);\n} catch (error) {\n console.error(`[microi-dsh-bootstrap] ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n}\n"]
10
+ args: ["-e","/*\n * DeepSeek Harness 通过 profile bundle 加载此 `node -e` 引导脚本。\n * DSH 不保证 MCP 子进程 cwd 位于 npm 包根,因此按 DSH_HOME/profile 定位\n * 当前版本的 @microi.net/cli,再复用 Codex 同源适配器与多连接路由器。\n */\nconst fs = require('node:fs');\nconst os = require('node:os');\nconst path = require('node:path');\nconst packageName = '@microi.net/cli';\nconst expectedVersion = '5.2.9';\n\nfunction readJson(filePath) {\n try { return JSON.parse(fs.readFileSync(filePath, 'utf8')); }\n catch { return undefined; }\n}\n\nfunction expandHome(value) {\n if (value === '~') return os.homedir();\n if (value.startsWith('~/') || value.startsWith('~\\\\')) return path.join(os.homedir(), value.slice(2));\n return value;\n}\n\nfunction validRoot(value) {\n const root = path.resolve(value);\n const pkg = readJson(path.join(root, 'package.json'));\n const patch = path.join(root, 'cordis.patch.yml');\n const adapter = path.join(root, 'scripts', 'mcp-codex-stdio-adapter.js');\n const router = path.join(root, 'scripts', 'microi-codex-router.js');\n if (pkg?.name !== packageName || pkg?.version !== expectedVersion) return undefined;\n if (pkg?.dsh?.bundle?.patch !== './cordis.patch.yml') return undefined;\n if (![patch, adapter, router].every(filePath => fs.existsSync(filePath))) return undefined;\n return { root: fs.realpathSync(root), adapter, router, modifiedAt: fs.statSync(router).mtimeMs };\n}\n\nfunction findPlugin() {\n const explicit = String(process.env.MICROI_DSH_PLUGIN_ROOT || '').trim();\n if (explicit) {\n const plugin = validRoot(explicit);\n if (!plugin) throw new Error(`MICROI_DSH_PLUGIN_ROOT 不是版本 ${expectedVersion} 的有效 Microi DSH bundle:${explicit}`);\n return plugin;\n }\n const configuredHome = String(process.env.DSH_HOME || '').trim();\n const dshHome = path.resolve(expandHome(configuredHome || path.join(os.homedir(), '.dsh')));\n const profilesRoot = path.join(dshHome, 'profiles');\n const candidates = [];\n if (fs.existsSync(profilesRoot)) {\n for (const entry of fs.readdirSync(profilesRoot, { withFileTypes: true })) {\n if (!entry.isDirectory() || entry.name === 'node_modules') continue;\n const root = path.join(profilesRoot, entry.name, 'node_modules', '@microi.net', 'cli');\n const plugin = validRoot(root);\n if (plugin) candidates.push(plugin);\n }\n }\n candidates.sort((left, right) => right.modifiedAt - left.modifiedAt);\n if (!candidates[0]) throw new Error(`未在 ${profilesRoot} 找到版本 ${expectedVersion} 的 ${packageName}`);\n return candidates[0];\n}\n\ntry {\n const plugin = findPlugin();\n process.env.MICROI_DSH_PLUGIN_ROOT = plugin.root;\n process.env.MICROI_CODEX_PLUGIN_ROOT = plugin.root;\n process.env.MICROI_TOOL_SOURCE = 'dsh';\n process.env.MICROI_TOOL_VERSION = expectedVersion;\n process.env.MICROI_WORKSPACE_ROOT = process.env.MICROI_WORKSPACE_ROOT || process.cwd();\n process.argv[2] = plugin.router;\n require(plugin.adapter);\n} catch (error) {\n console.error(`[microi-dsh-bootstrap] ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n}\n"]
11
11
  env:
12
12
  MICROI_TOOL_SOURCE: dsh
13
13
  cwd: !!js process.cwd()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microi.net/cli",
3
- "version": "5.2.8",
3
+ "version": "5.2.9",
4
4
  "description": "Microi吾码 AI 开发 CLI 与多宿主 Plugin:服务器连接、Skills、MCP、V8 同步和低代码交付",
5
5
  "license": "MIT",
6
6
  "homepage": "https://microi.net/doc/v8-engine/vs-code-plugin.html",
@@ -1,13 +1,13 @@
1
1
  {
2
- "builtAt": "2026-08-25T00:14:29.656Z",
2
+ "builtAt": "2026-08-25T02:18:22.909Z",
3
3
  "source": "../microi.skills",
4
4
  "extension": {
5
5
  "name": "v8-engine",
6
- "version": "5.2.8",
6
+ "version": "5.2.9",
7
7
  "publisher": "Microi"
8
8
  },
9
9
  "skills": {
10
- "version": "5.2.8",
10
+ "version": "5.2.9",
11
11
  "versionRule": "Microi version uses three numeric parts. Each publish increments the last part; when a part exceeds 9 it carries to the previous part: 1.0.9 -> 1.1.0, 1.9.9 -> 2.0.0.",
12
12
  "managedBy": "Microi.VSCode/bump-version.js"
13
13
  },
@@ -15,10 +15,10 @@
15
15
  "dir": "dist/microi.skills",
16
16
  "files": 178,
17
17
  "skills": 65,
18
- "bytes": 2250096
18
+ "bytes": 2254645
19
19
  },
20
20
  "fileHashes": {
21
- ".microi-skills-version.json": "ad39d3393432fa2341308d8b5926a7a3bb839d18a6413cad2472dab561150b12",
21
+ ".microi-skills-version.json": "2d77a79b32af4fa267caa2bb96e98c9a4e4df9798ea6f14eca36518bb78623d3",
22
22
  ".progressive-disclosure-manifest.json": "647fb9b710b958ca64713c45bb0e8a17252ec7f2913179327a26525a2cd5a31d",
23
23
  "README.md": "332aade05015acac5f1387829a42529f37fc203ff0fcfb2f16cc3afdbb23b1ed",
24
24
  "ai-engine/SKILL.md": "df63cf56bd06027f30bd0597003c65b479049141fc0b4a31d33cbc9a5fa044cf",
@@ -34,16 +34,16 @@
34
34
  "dos-orm/references/api-reference.md": "facc5e62cd6439a06263580dab9656271118d4bb5a91b5d9230a79136e6daa72",
35
35
  "job-engine/SKILL.md": "5d3322f183475bdb7acfa157112bcee3b859b740caeafb57a7afaba0efb58d0d",
36
36
  "job-engine/agents/openai.yaml": "65889ee39bc34caca9085539d8954a381aab93590c5635eea3bb6f4c001934af",
37
- "message-notification/SKILL.md": "6a74c82fa2aa4295a027c72e3cd364dc71e0836fd77d5ae207cbbfa24fcbd2ee",
37
+ "message-notification/SKILL.md": "09b6b9b8ba67627cb4603a69a3a6530db943ffec92adcb520a50da00fad00ee1",
38
38
  "message-notification/agents/openai.yaml": "d0e259921410e94caaf8b376d690a529842446e3f32c9523b7dfd1bda599f58c",
39
- "message-notification/references/contracts.md": "752a5acdd6481dd2386d116eaa8b59401dcef8fc07185208c5e835e17b979afe",
40
- "microi-ai-app-auth.js": "8023db6ae655bc33027f389a64ef7937ac09da35eb1b8a497aaefb986834242a",
39
+ "message-notification/references/contracts.md": "fd520821d533ead45ab6a476bd53cab79b19219cd46ef26120181dbd35dfcb0d",
40
+ "microi-ai-app-auth.js": "e7f62522709eca196dea9c4170da8095cef69dfdf96e00dc470825a6cf4e2a01",
41
41
  "microi-ai-application/SKILL.md": "de48dd57de350dcc3e605bc5075ff0d6cfa33e7f7e450e59cbdd6afe32e02e0b",
42
42
  "microi-ai-application/agents/openai.yaml": "d3dfc4d0f2fda3391e90e661ca9d8d051cb43824b011d1a88e99db135870454f",
43
43
  "microi-ai-application/references/frontend-baseline.md": "c21a2d38292fd8d445a7538afb45d609881f624f32d39c0fc4bbbb3c2fa64a74",
44
44
  "microi-client-frontend/SKILL.md": "097c2dc3b06741678bcaccca6eb24bb4b65770e356f5f947d5d9b087a2e8ae8c",
45
- "microi-client-frontend/references/progressive-01-3-动态按钮系统.md": "c4e90cadc53d2d08b747e896a7e520db2513a3f404535b4c287bfccd090edb6a",
46
- "microi-client-frontend/references/progressive-02-8-运行时高频坑复盘.md": "899a15f52cd849b1f5b48139fbec626423ebdae586032ad73801842f5701a3fe",
45
+ "microi-client-frontend/references/progressive-01-3-动态按钮系统.md": "3aa2cdbd37ed6ff6927ba76b7fbd15a4e0855d8b84e77603793182a778a33438",
46
+ "microi-client-frontend/references/progressive-02-8-运行时高频坑复盘.md": "485de240a2e1d79f069b4845ac835847fffd64fdd3a5e805fc7d4e2f5bdf1d6a",
47
47
  "microi-client-frontend/references/progressive-03-vue3-前端微服务宿主规则.md": "bf78d9d2e2d6d1a8315f44f04f21889b21d845a02801d5f8e0eb11b3f490b6d1",
48
48
  "microi-codex-installer/SKILL.md": "75bec07d087167ab6343c816d07d9c7e1e850871a05737f31aec115e7fa3cdce",
49
49
  "microi-codex-installer/agents/openai.yaml": "e531219b74a70204893a156b1c22c69013a4c9d24b132ead912746b1b312cf80",
@@ -66,12 +66,12 @@
66
66
  "microi-form-engine/references/data-source-events.md": "59a95a36624476b12cdc84e4c23975d074b1f115df19992fd0fd075bb982e7cb",
67
67
  "microi-form-layout/SKILL.md": "ce4278f50cd5cea54a20b082525b1a94b58baa7745a27bec626b71725affa061",
68
68
  "microi-form-layout/references/progressive-01-3-三种分组的存储与配置.md": "b72f79f9cf7635d0add29aa954c9dc0d333a62f45ee1d6113fbd7ee250b26965",
69
- "microi-frontend-sdk/SKILL.md": "84cf1465c441315413520922317a8998598bd419d544e403640c32c7c59b5d70",
69
+ "microi-frontend-sdk/SKILL.md": "391a1da2720c4537a9465fa73cf2182b86ba6a7b0028696c38fe9f6478100afc",
70
70
  "microi-frontend-sdk/references/progressive-01-token-当前登录用户与当前终端登录协议.md": "5dea28edec5a31b6e6e5e15fefc03df9d1ad9bd4b583388fc77bd2aa67a19165",
71
71
  "microi-left-right-layout/SKILL.md": "e2f051bce91e6b7cd103599ea526d543fd0f8caaa4c92c71e9e5d81b1a90cf7d",
72
72
  "microi-microservice/SKILL.md": "6714aac779aa0d64d95594a180c0bf72a2c0b41fd21de3894e84643665865532",
73
73
  "microi-microservice/references/runtime-delivery.md": "538ae295826892942b365492b11aa4797599ea7047fc69409aae64ed99ecfe9b",
74
- "microi-mobile-app-quality/SKILL.md": "79cb796df3a486c9a39db10d47df53d9dafb259826067799486def659683144a",
74
+ "microi-mobile-app-quality/SKILL.md": "5f096599d539faf2fd57da23686497cf85eb75b4e5c18cc26704c3a856f2f995",
75
75
  "microi-mobile-app-quality/references/progressive-01-4-重要按钮必须带图标.md": "ec938bd1a64b9896ff5d3165ad217ee5c68a22a51ddb690d8a8a0c7a9365c512",
76
76
  "microi-mobile-app-quality/references/progressive-02-9-主题切换必须真实且全局生效.md": "070ad110ed5a87046b2daf36c899debe2f1d08680148f6ff7549be4432bd3492",
77
77
  "microi-solution-quotation/SKILL.md": "d99886d1261dba1c56b8ef70090783ffe9ae8a4915f5ca2c7e1fae6be519567a",
@@ -84,13 +84,13 @@
84
84
  "microi-sso/references/outbound.md": "236da363eea139a19264e956c94e0cc90da69a0a6c21505d0e02e682d8c506bc",
85
85
  "microi-system-delivery/SKILL.md": "06502e440efa37689a0d98bfa34f960d882a80fb1d1ab1e87ec36868c2af09cc",
86
86
  "microi-system-delivery/references/progressive-01-标准工作流.md": "02c9fe51cab2216fc58fb4a18a6acb43b3318864a5a74cac2990e848e3e19c4b",
87
- "microi-system-delivery/references/progressive-02-自动化测试必须覆盖的坑.md": "dee8e3f2363548e4c83519f8784f8e8bfafe8dd3058f28c49d525dc93c542753",
87
+ "microi-system-delivery/references/progressive-02-自动化测试必须覆盖的坑.md": "65acd38ad85744c7fd69d23bb65c25269e293a4085fed2bbef2ee2aeb4c232d0",
88
88
  "microi-ui/SKILL.md": "1136593475e94d55799dde302e8e86f1e96dd101e5f4645fd4d8091faa52f5d6",
89
89
  "microi-ui/references/progressive-01-移动端场景蓝图.md": "aec5e6a400cec7a4cc4e474ad7033bc69874920ebd554706656034ffb9dc8c00",
90
- "microi-uniapp-frontend/SKILL.md": "b4e7ae93b10a9944197fc1221adab88dcaf168f9ec6d56adbabc210e7665ec4b",
90
+ "microi-uniapp-frontend/SKILL.md": "1ef0905b45007706d5a40d829edcbe62103373aabb1c9846b4aa0cf15edff8d1",
91
91
  "microi-uniapp-frontend/references/progressive-01-移动端分类-双栏列表独立滚动.md": "44df3c20120298f6565cf4388eadca70d98d097880c61168ce6d3ac03e80968b",
92
92
  "microi-uniapp-frontend/references/progressive-02-关键业务资产不得默认选中.md": "31a0a12e39ec785df038fb5c73d4978d6dec42d86c52b79e91082c9ac13f29cf",
93
- "microi.v8.js": "03d1dcc661b3c329f7f5f62083d1f674b082b9850ed952e0d67dfc98e5133c94",
93
+ "microi.v8.js": "66db7602fe838944fd5b89b59148517a303da574f3f40acadbe7102b8599aa25",
94
94
  "module-engine/SKILL.md": "64c899b916aca60189b5cb02abe6577d686bcd3820188970d32f751699196266",
95
95
  "module-engine/references/module-config.md": "9e8ac8a7f65d6b563f938193d4b7c6b230d878a3513fc2a90c8b780e70ddd353",
96
96
  "ocr-engine/SKILL.md": "239fed8ba28c0178fbbcc4c3dc8d4f3b8b8cf1d2b794db2014c2600ea7835da6",
@@ -153,8 +153,8 @@
153
153
  "v8-export-import/references/progressive-02-powerpoint-导出.md": "5837905a195be7c38fe37e0abd40eee95a8bc26acdab1f3a9aba01c264a125ae",
154
154
  "v8-export-import/references/progressive-03-安全-性能注意.md": "a2acc492740eb693be5a0ad275cabcba7a813aa7378c844e43b04233d03a9d0c",
155
155
  "v8-file-upload/SKILL.md": "d05c6f18e4099ce67f3f56ded1c2934fa4a0224d5bc9fc9ff34d92a8e4df8192",
156
- "v8-file-upload/references/progressive-01-公有桶-vs-私有桶.md": "bd81f9f6a07251016dd8abb7ce52b1148685c47116b0aadd3082bf8bc7587774",
157
- "v8-file-upload/references/progressive-02-office-文件在线编辑版本号规则.md": "ab5a0d6f9e0f39a036d48d7f87cfac8aed5575f42dcbabc9f34ad723ade2e1be",
156
+ "v8-file-upload/references/progressive-01-公有桶-vs-私有桶.md": "0e78e6f7db21415cea0fe94d58ded7f3159068a21fdd39e1f295b14f4dc9961f",
157
+ "v8-file-upload/references/progressive-02-office-文件在线编辑版本号规则.md": "4e1027b52ab21db3b16d4d374736ae6abd30d9415b5fdf7a6ee41f73c30468c5",
158
158
  "v8-formengine-http/SKILL.md": "8338e9087e93bb41ad260863b076db387373c606e481bf49809c447083c761d1",
159
159
  "v8-frontend-events/SKILL.md": "ae476d6dde9b8251100f61411e9ff86ce9e885df651eb599015fa2a121b0270e",
160
160
  "v8-frontend-events/references/bluetooth-print-api.md": "ce7f2448dc79e7eb946646784619b47501bdff1651253fc5e82fc91ee41ea6c8",
@@ -188,7 +188,7 @@
188
188
  "v8-template-engine/SKILL.md": "19363a9e047737b62236f187946ac8398ee6cb19907de70ce0888681b75afb15",
189
189
  "v8-utilities/SKILL.md": "2cf8fc6d1a9296ea60bb89ea1b130ac5c9a1f9eb94802fed0cceaf8b61de1b30",
190
190
  "v8-utilities/references/client-api-index.md": "3362126197bd34191640d6bd532b16f1ed446c4a8a9d805f4973be5d58b90a4a",
191
- "v8-utilities/references/platform-http-routes.md": "ad07cc0c6b54a155cc22d071783ccef92cff2c295dcc09bb34da604c341d934f",
191
+ "v8-utilities/references/platform-http-routes.md": "36a28da8f294eac6cf0b853bb58c88050fe19ac0ffe98daff71cd0c786669da4",
192
192
  "v8-utilities/references/server-api-index.md": "8e4392ac26fcf0c2a4715d966d526cb142a077dfb68bea0a117971ffaf23bc15",
193
193
  "v8-workflow/SKILL.md": "d068ceded6f338fece9443f354dff21dfcf744dd192dd6329b2e98692bb8181e",
194
194
  "v8-workflow/references/progressive-01-节点开始-v8-事件.md": "9b6b01e7ac03c0a11bc837671a30107ff5c5f253029d74fd17713084104d7e99",
@@ -198,184 +198,184 @@
198
198
  "workspace-conventions/references/progressive-03-cli-与-ide-插件错版共存约定.md": "86db1f03700fd54dd824d28c553c678202e8f74b796fd0f9d91f63bf53a530b1"
199
199
  },
200
200
  "fileVersions": {
201
- ".microi-skills-version.json": "5.2.8",
202
- ".progressive-disclosure-manifest.json": "5.2.8",
203
- "README.md": "5.2.8",
204
- "ai-engine/SKILL.md": "5.2.8",
205
- "ai-engine/agents/openai.yaml": "5.2.8",
206
- "ai-platform-governance/SKILL.md": "5.2.8",
207
- "ai-platform-governance/references/progressive-01-功能开关.md": "5.2.8",
208
- "app-store/SKILL.md": "5.2.8",
209
- "app-store/agents/openai.yaml": "5.2.8",
210
- "business-blueprint/SKILL.md": "5.2.8",
211
- "datasource-engine/SKILL.md": "5.2.8",
212
- "datasource-engine/agents/openai.yaml": "5.2.8",
213
- "dos-orm/SKILL.md": "5.2.8",
214
- "dos-orm/references/api-reference.md": "5.2.8",
215
- "job-engine/SKILL.md": "5.2.8",
216
- "job-engine/agents/openai.yaml": "5.2.8",
217
- "message-notification/SKILL.md": "5.2.8",
218
- "message-notification/agents/openai.yaml": "5.2.8",
219
- "message-notification/references/contracts.md": "5.2.8",
220
- "microi-ai-app-auth.js": "5.2.8",
221
- "microi-ai-application/SKILL.md": "5.2.8",
222
- "microi-ai-application/agents/openai.yaml": "5.2.8",
223
- "microi-ai-application/references/frontend-baseline.md": "5.2.8",
224
- "microi-client-frontend/SKILL.md": "5.2.8",
225
- "microi-client-frontend/references/progressive-01-3-动态按钮系统.md": "5.2.8",
226
- "microi-client-frontend/references/progressive-02-8-运行时高频坑复盘.md": "5.2.8",
227
- "microi-client-frontend/references/progressive-03-vue3-前端微服务宿主规则.md": "5.2.8",
228
- "microi-codex-installer/SKILL.md": "5.2.8",
229
- "microi-codex-installer/agents/openai.yaml": "5.2.8",
230
- "microi-codex/SKILL.md": "5.2.8",
231
- "microi-datasource-mapping/SKILL.md": "5.2.8",
232
- "microi-db-schema/SKILL.md": "5.2.8",
233
- "microi-db-schema/agents/openai.yaml": "5.2.8",
234
- "microi-db-schema/references/core-tables.md": "5.2.8",
235
- "microi-db-schema/references/form-component-options.md": "5.2.8",
236
- "microi-db-schema/references/schema-overview.md": "5.2.8",
237
- "microi-db-schema/references/schema.md": "5.2.8",
238
- "microi-db-schema/references/table-catalog.md": "5.2.8",
239
- "microi-deployment/SKILL.md": "5.2.8",
240
- "microi-deployment/references/deployment-matrix.md": "5.2.8",
241
- "microi-docs-coverage/SKILL.md": "5.2.8",
242
- "microi-docs-coverage/references/capability-map.md": "5.2.8",
243
- "microi-docs-coverage/scripts/audit-doc-skill-coverage.mjs": "5.2.8",
244
- "microi-form-engine/SKILL.md": "5.2.8",
245
- "microi-form-engine/references/component-catalog.md": "5.2.8",
246
- "microi-form-engine/references/data-source-events.md": "5.2.8",
247
- "microi-form-layout/SKILL.md": "5.2.8",
248
- "microi-form-layout/references/progressive-01-3-三种分组的存储与配置.md": "5.2.8",
249
- "microi-frontend-sdk/SKILL.md": "5.2.8",
250
- "microi-frontend-sdk/references/progressive-01-token-当前登录用户与当前终端登录协议.md": "5.2.8",
251
- "microi-left-right-layout/SKILL.md": "5.2.8",
252
- "microi-microservice/SKILL.md": "5.2.8",
253
- "microi-microservice/references/runtime-delivery.md": "5.2.8",
254
- "microi-mobile-app-quality/SKILL.md": "5.2.8",
255
- "microi-mobile-app-quality/references/progressive-01-4-重要按钮必须带图标.md": "5.2.8",
256
- "microi-mobile-app-quality/references/progressive-02-9-主题切换必须真实且全局生效.md": "5.2.8",
257
- "microi-solution-quotation/SKILL.md": "5.2.8",
258
- "microi-solution-quotation/agents/openai.yaml": "5.2.8",
259
- "microi-solution-quotation/scripts/build_solution_quote.py": "5.2.8",
260
- "microi-sso/SKILL.md": "5.2.8",
261
- "microi-sso/references/acceptance.md": "5.2.8",
262
- "microi-sso/references/configuration-and-security.md": "5.2.8",
263
- "microi-sso/references/inbound.md": "5.2.8",
264
- "microi-sso/references/outbound.md": "5.2.8",
265
- "microi-system-delivery/SKILL.md": "5.2.8",
266
- "microi-system-delivery/references/progressive-01-标准工作流.md": "5.2.8",
267
- "microi-system-delivery/references/progressive-02-自动化测试必须覆盖的坑.md": "5.2.8",
268
- "microi-ui/SKILL.md": "5.2.8",
269
- "microi-ui/references/progressive-01-移动端场景蓝图.md": "5.2.8",
270
- "microi-uniapp-frontend/SKILL.md": "5.2.8",
271
- "microi-uniapp-frontend/references/progressive-01-移动端分类-双栏列表独立滚动.md": "5.2.8",
272
- "microi-uniapp-frontend/references/progressive-02-关键业务资产不得默认选中.md": "5.2.8",
273
- "microi.v8.js": "5.2.8",
274
- "module-engine/SKILL.md": "5.2.8",
275
- "module-engine/references/module-config.md": "5.2.8",
276
- "ocr-engine/SKILL.md": "5.2.8",
277
- "ocr-engine/agents/openai.yaml": "5.2.8",
278
- "page-engine/SKILL.md": "5.2.8",
279
- "page-engine/references/progressive-01-所有组件类型.md": "5.2.8",
280
- "page-engine/references/progressive-02-版本历史-并发保存与回滚.md": "5.2.8",
281
- "performance-testing/SKILL.md": "5.2.8",
282
- "playwright-e2e/SKILL.md": "5.2.8",
283
- "playwright-e2e/references/progressive-01-全自动登录-免验证码-但不免密码-必读.md": "5.2.8",
284
- "playwright-e2e/references/progressive-02-文字对比度与可读性自动化检查-必做.md": "5.2.8",
285
- "playwright-e2e/references/progressive-03-microi-helper-模板.md": "5.2.8",
286
- "playwright-e2e/references/progressive-04-ci-建议.md": "5.2.8",
287
- "print-engine/SKILL.md": "5.2.8",
288
- "production-readonly-audit/SKILL.md": "5.2.8",
289
- "report-engine/SKILL.md": "5.2.8",
290
- "report-engine/agents/openai.yaml": "5.2.8",
291
- "scripts/optimize-progressive-disclosure.mjs": "5.2.8",
292
- "scripts/refresh-progressive-disclosure.mjs": "5.2.8",
293
- "scripts/validate-progressive-disclosure.mjs": "5.2.8",
294
- "search-engine/SKILL.md": "5.2.8",
295
- "search-engine/agents/openai.yaml": "5.2.8",
296
- "spider-engine/SKILL.md": "5.2.8",
297
- "system-observability/SKILL.md": "5.2.8",
298
- "translate-engine/SKILL.md": "5.2.8",
299
- "translate-engine/agents/openai.yaml": "5.2.8",
300
- "ui-design/SKILL.md": "5.2.8",
301
- "ui-design/assets/pattern-showcase/app.js": "5.2.8",
302
- "ui-design/assets/pattern-showcase/index.html": "5.2.8",
303
- "ui-design/assets/pattern-showcase/styles.css": "5.2.8",
304
- "ui-design/assets/templates/MCI-DESIGN.md": "5.2.8",
305
- "ui-design/references/design-pattern-library.md": "5.2.8",
306
- "ui-design/references/mci-design-contract.md": "5.2.8",
307
- "ui-design/references/motion-and-media.md": "5.2.8",
308
- "ui-design/references/product-flow-recipes.md": "5.2.8",
309
- "ui-design/references/progressive-01-颜色体系-css-variables-支持主题切换.md": "5.2.8",
310
- "ui-design/references/progressive-02-字体.md": "5.2.8",
311
- "ui-design/references/progressive-03-动效规范-丰富但不卡.md": "5.2.8",
312
- "ui-design/references/progressive-04-组件风格速查.md": "5.2.8",
313
- "ui-design/references/progressive-05-移动端专用规范.md": "5.2.8",
314
- "ui-design/references/progressive-06-主题切换实现.md": "5.2.8",
315
- "ui-design/references/progressive-07-速查-从头搭建一个移动端页面.md": "5.2.8",
316
- "ui-design/references/progressive-08-表单分组规范-tabs-vs-collapsegroup-强制.md": "5.2.8",
317
- "uniapp-mall-assets/SKILL.md": "5.2.8",
318
- "unity-integration/SKILL.md": "5.2.8",
319
- "unity-integration/agents/openai.yaml": "5.2.8",
320
- "unity-integration/references/ai-app-delivery.md": "5.2.8",
321
- "unity-integration/references/sdk-api.md": "5.2.8",
322
- "unity-integration/references/toolbox-migration.md": "5.2.8",
323
- "unity-integration/references/webgl-hosting.md": "5.2.8",
324
- "v8-api-config/SKILL.md": "5.2.8",
325
- "v8-cache-pattern/SKILL.md": "5.2.8",
326
- "v8-crud-api/SKILL.md": "5.2.8",
327
- "v8-crud-api/references/progressive-01-查询列表-分页.md": "5.2.8",
328
- "v8-crud-api/references/progressive-02-where-条件语法速查.md": "5.2.8",
329
- "v8-debugging/SKILL.md": "5.2.8",
330
- "v8-explorer-tree/SKILL.md": "5.2.8",
331
- "v8-export-import/SKILL.md": "5.2.8",
332
- "v8-export-import/references/progressive-01-excellayout-高级自由布局.md": "5.2.8",
333
- "v8-export-import/references/progressive-02-powerpoint-导出.md": "5.2.8",
334
- "v8-export-import/references/progressive-03-安全-性能注意.md": "5.2.8",
335
- "v8-file-upload/SKILL.md": "5.2.8",
336
- "v8-file-upload/references/progressive-01-公有桶-vs-私有桶.md": "5.2.8",
337
- "v8-file-upload/references/progressive-02-office-文件在线编辑版本号规则.md": "5.2.8",
338
- "v8-formengine-http/SKILL.md": "5.2.8",
339
- "v8-frontend-events/SKILL.md": "5.2.8",
340
- "v8-frontend-events/references/bluetooth-print-api.md": "5.2.8",
341
- "v8-frontend-events/references/bluetooth-print.md": "5.2.8",
342
- "v8-frontend-events/references/progressive-01-列表事件.md": "5.2.8",
343
- "v8-http-integration/SKILL.md": "5.2.8",
344
- "v8-http-integration/references/progressive-01-get-请求.md": "5.2.8",
345
- "v8-http-integration/references/progressive-02-错误处理模式.md": "5.2.8",
346
- "v8-image-processing/SKILL.md": "5.2.8",
347
- "v8-image-processing/agents/openai.yaml": "5.2.8",
348
- "v8-image-processing/references/api-reference.md": "5.2.8",
349
- "v8-menu-buttons/SKILL.md": "5.2.8",
350
- "v8-menu-buttons/references/progressive-01-2-按钮对象-schema.md": "5.2.8",
351
- "v8-menu-buttons/references/progressive-02-8-模式-f-后台任务按钮-长任务.md": "5.2.8",
352
- "v8-menu-buttons/references/progressive-03-10-反模式-避免.md": "5.2.8",
353
- "v8-mongodb/SKILL.md": "5.2.8",
354
- "v8-mq-mqtt/SKILL.md": "5.2.8",
355
- "v8-mq-mqtt/references/mqtt-production.md": "5.2.8",
356
- "v8-mq-mqtt/references/progressive-01-v8-mqtt-iot-物联网.md": "5.2.8",
357
- "v8-mq-mqtt/scripts/check-mqtt-skill-coverage.mjs": "5.2.8",
358
- "v8-saas-multi-tenant/SKILL.md": "5.2.8",
359
- "v8-security/SKILL.md": "5.2.8",
360
- "v8-security/references/progressive-01-2-权限校验.md": "5.2.8",
361
- "v8-security/references/progressive-02-7-日志记录.md": "5.2.8",
362
- "v8-sql-query/SKILL.md": "5.2.8",
363
- "v8-table-event/SKILL.md": "5.2.8",
364
- "v8-table-event/references/progressive-01-informv8-js-表单打开事件.md": "5.2.8",
365
- "v8-table-event/references/progressive-02-前端事件名-v8-eventname-可能的值.md": "5.2.8",
366
- "v8-tcp-integration/SKILL.md": "5.2.8",
367
- "v8-tcp-integration/agents/openai.yaml": "5.2.8",
368
- "v8-template-engine/SKILL.md": "5.2.8",
369
- "v8-utilities/SKILL.md": "5.2.8",
370
- "v8-utilities/references/client-api-index.md": "5.2.8",
371
- "v8-utilities/references/platform-http-routes.md": "5.2.8",
372
- "v8-utilities/references/server-api-index.md": "5.2.8",
373
- "v8-workflow/SKILL.md": "5.2.8",
374
- "v8-workflow/references/progressive-01-节点开始-v8-事件.md": "5.2.8",
375
- "workspace-conventions/SKILL.md": "5.2.8",
376
- "workspace-conventions/references/progressive-01-版本更新日志保护规则-强制.md": "5.2.8",
377
- "workspace-conventions/references/progressive-02-microi-net-api-本地启动约定.md": "5.2.8",
378
- "workspace-conventions/references/progressive-03-cli-与-ide-插件错版共存约定.md": "5.2.8"
201
+ ".microi-skills-version.json": "5.2.9",
202
+ ".progressive-disclosure-manifest.json": "5.2.9",
203
+ "README.md": "5.2.9",
204
+ "ai-engine/SKILL.md": "5.2.9",
205
+ "ai-engine/agents/openai.yaml": "5.2.9",
206
+ "ai-platform-governance/SKILL.md": "5.2.9",
207
+ "ai-platform-governance/references/progressive-01-功能开关.md": "5.2.9",
208
+ "app-store/SKILL.md": "5.2.9",
209
+ "app-store/agents/openai.yaml": "5.2.9",
210
+ "business-blueprint/SKILL.md": "5.2.9",
211
+ "datasource-engine/SKILL.md": "5.2.9",
212
+ "datasource-engine/agents/openai.yaml": "5.2.9",
213
+ "dos-orm/SKILL.md": "5.2.9",
214
+ "dos-orm/references/api-reference.md": "5.2.9",
215
+ "job-engine/SKILL.md": "5.2.9",
216
+ "job-engine/agents/openai.yaml": "5.2.9",
217
+ "message-notification/SKILL.md": "5.2.9",
218
+ "message-notification/agents/openai.yaml": "5.2.9",
219
+ "message-notification/references/contracts.md": "5.2.9",
220
+ "microi-ai-app-auth.js": "5.2.9",
221
+ "microi-ai-application/SKILL.md": "5.2.9",
222
+ "microi-ai-application/agents/openai.yaml": "5.2.9",
223
+ "microi-ai-application/references/frontend-baseline.md": "5.2.9",
224
+ "microi-client-frontend/SKILL.md": "5.2.9",
225
+ "microi-client-frontend/references/progressive-01-3-动态按钮系统.md": "5.2.9",
226
+ "microi-client-frontend/references/progressive-02-8-运行时高频坑复盘.md": "5.2.9",
227
+ "microi-client-frontend/references/progressive-03-vue3-前端微服务宿主规则.md": "5.2.9",
228
+ "microi-codex-installer/SKILL.md": "5.2.9",
229
+ "microi-codex-installer/agents/openai.yaml": "5.2.9",
230
+ "microi-codex/SKILL.md": "5.2.9",
231
+ "microi-datasource-mapping/SKILL.md": "5.2.9",
232
+ "microi-db-schema/SKILL.md": "5.2.9",
233
+ "microi-db-schema/agents/openai.yaml": "5.2.9",
234
+ "microi-db-schema/references/core-tables.md": "5.2.9",
235
+ "microi-db-schema/references/form-component-options.md": "5.2.9",
236
+ "microi-db-schema/references/schema-overview.md": "5.2.9",
237
+ "microi-db-schema/references/schema.md": "5.2.9",
238
+ "microi-db-schema/references/table-catalog.md": "5.2.9",
239
+ "microi-deployment/SKILL.md": "5.2.9",
240
+ "microi-deployment/references/deployment-matrix.md": "5.2.9",
241
+ "microi-docs-coverage/SKILL.md": "5.2.9",
242
+ "microi-docs-coverage/references/capability-map.md": "5.2.9",
243
+ "microi-docs-coverage/scripts/audit-doc-skill-coverage.mjs": "5.2.9",
244
+ "microi-form-engine/SKILL.md": "5.2.9",
245
+ "microi-form-engine/references/component-catalog.md": "5.2.9",
246
+ "microi-form-engine/references/data-source-events.md": "5.2.9",
247
+ "microi-form-layout/SKILL.md": "5.2.9",
248
+ "microi-form-layout/references/progressive-01-3-三种分组的存储与配置.md": "5.2.9",
249
+ "microi-frontend-sdk/SKILL.md": "5.2.9",
250
+ "microi-frontend-sdk/references/progressive-01-token-当前登录用户与当前终端登录协议.md": "5.2.9",
251
+ "microi-left-right-layout/SKILL.md": "5.2.9",
252
+ "microi-microservice/SKILL.md": "5.2.9",
253
+ "microi-microservice/references/runtime-delivery.md": "5.2.9",
254
+ "microi-mobile-app-quality/SKILL.md": "5.2.9",
255
+ "microi-mobile-app-quality/references/progressive-01-4-重要按钮必须带图标.md": "5.2.9",
256
+ "microi-mobile-app-quality/references/progressive-02-9-主题切换必须真实且全局生效.md": "5.2.9",
257
+ "microi-solution-quotation/SKILL.md": "5.2.9",
258
+ "microi-solution-quotation/agents/openai.yaml": "5.2.9",
259
+ "microi-solution-quotation/scripts/build_solution_quote.py": "5.2.9",
260
+ "microi-sso/SKILL.md": "5.2.9",
261
+ "microi-sso/references/acceptance.md": "5.2.9",
262
+ "microi-sso/references/configuration-and-security.md": "5.2.9",
263
+ "microi-sso/references/inbound.md": "5.2.9",
264
+ "microi-sso/references/outbound.md": "5.2.9",
265
+ "microi-system-delivery/SKILL.md": "5.2.9",
266
+ "microi-system-delivery/references/progressive-01-标准工作流.md": "5.2.9",
267
+ "microi-system-delivery/references/progressive-02-自动化测试必须覆盖的坑.md": "5.2.9",
268
+ "microi-ui/SKILL.md": "5.2.9",
269
+ "microi-ui/references/progressive-01-移动端场景蓝图.md": "5.2.9",
270
+ "microi-uniapp-frontend/SKILL.md": "5.2.9",
271
+ "microi-uniapp-frontend/references/progressive-01-移动端分类-双栏列表独立滚动.md": "5.2.9",
272
+ "microi-uniapp-frontend/references/progressive-02-关键业务资产不得默认选中.md": "5.2.9",
273
+ "microi.v8.js": "5.2.9",
274
+ "module-engine/SKILL.md": "5.2.9",
275
+ "module-engine/references/module-config.md": "5.2.9",
276
+ "ocr-engine/SKILL.md": "5.2.9",
277
+ "ocr-engine/agents/openai.yaml": "5.2.9",
278
+ "page-engine/SKILL.md": "5.2.9",
279
+ "page-engine/references/progressive-01-所有组件类型.md": "5.2.9",
280
+ "page-engine/references/progressive-02-版本历史-并发保存与回滚.md": "5.2.9",
281
+ "performance-testing/SKILL.md": "5.2.9",
282
+ "playwright-e2e/SKILL.md": "5.2.9",
283
+ "playwright-e2e/references/progressive-01-全自动登录-免验证码-但不免密码-必读.md": "5.2.9",
284
+ "playwright-e2e/references/progressive-02-文字对比度与可读性自动化检查-必做.md": "5.2.9",
285
+ "playwright-e2e/references/progressive-03-microi-helper-模板.md": "5.2.9",
286
+ "playwright-e2e/references/progressive-04-ci-建议.md": "5.2.9",
287
+ "print-engine/SKILL.md": "5.2.9",
288
+ "production-readonly-audit/SKILL.md": "5.2.9",
289
+ "report-engine/SKILL.md": "5.2.9",
290
+ "report-engine/agents/openai.yaml": "5.2.9",
291
+ "scripts/optimize-progressive-disclosure.mjs": "5.2.9",
292
+ "scripts/refresh-progressive-disclosure.mjs": "5.2.9",
293
+ "scripts/validate-progressive-disclosure.mjs": "5.2.9",
294
+ "search-engine/SKILL.md": "5.2.9",
295
+ "search-engine/agents/openai.yaml": "5.2.9",
296
+ "spider-engine/SKILL.md": "5.2.9",
297
+ "system-observability/SKILL.md": "5.2.9",
298
+ "translate-engine/SKILL.md": "5.2.9",
299
+ "translate-engine/agents/openai.yaml": "5.2.9",
300
+ "ui-design/SKILL.md": "5.2.9",
301
+ "ui-design/assets/pattern-showcase/app.js": "5.2.9",
302
+ "ui-design/assets/pattern-showcase/index.html": "5.2.9",
303
+ "ui-design/assets/pattern-showcase/styles.css": "5.2.9",
304
+ "ui-design/assets/templates/MCI-DESIGN.md": "5.2.9",
305
+ "ui-design/references/design-pattern-library.md": "5.2.9",
306
+ "ui-design/references/mci-design-contract.md": "5.2.9",
307
+ "ui-design/references/motion-and-media.md": "5.2.9",
308
+ "ui-design/references/product-flow-recipes.md": "5.2.9",
309
+ "ui-design/references/progressive-01-颜色体系-css-variables-支持主题切换.md": "5.2.9",
310
+ "ui-design/references/progressive-02-字体.md": "5.2.9",
311
+ "ui-design/references/progressive-03-动效规范-丰富但不卡.md": "5.2.9",
312
+ "ui-design/references/progressive-04-组件风格速查.md": "5.2.9",
313
+ "ui-design/references/progressive-05-移动端专用规范.md": "5.2.9",
314
+ "ui-design/references/progressive-06-主题切换实现.md": "5.2.9",
315
+ "ui-design/references/progressive-07-速查-从头搭建一个移动端页面.md": "5.2.9",
316
+ "ui-design/references/progressive-08-表单分组规范-tabs-vs-collapsegroup-强制.md": "5.2.9",
317
+ "uniapp-mall-assets/SKILL.md": "5.2.9",
318
+ "unity-integration/SKILL.md": "5.2.9",
319
+ "unity-integration/agents/openai.yaml": "5.2.9",
320
+ "unity-integration/references/ai-app-delivery.md": "5.2.9",
321
+ "unity-integration/references/sdk-api.md": "5.2.9",
322
+ "unity-integration/references/toolbox-migration.md": "5.2.9",
323
+ "unity-integration/references/webgl-hosting.md": "5.2.9",
324
+ "v8-api-config/SKILL.md": "5.2.9",
325
+ "v8-cache-pattern/SKILL.md": "5.2.9",
326
+ "v8-crud-api/SKILL.md": "5.2.9",
327
+ "v8-crud-api/references/progressive-01-查询列表-分页.md": "5.2.9",
328
+ "v8-crud-api/references/progressive-02-where-条件语法速查.md": "5.2.9",
329
+ "v8-debugging/SKILL.md": "5.2.9",
330
+ "v8-explorer-tree/SKILL.md": "5.2.9",
331
+ "v8-export-import/SKILL.md": "5.2.9",
332
+ "v8-export-import/references/progressive-01-excellayout-高级自由布局.md": "5.2.9",
333
+ "v8-export-import/references/progressive-02-powerpoint-导出.md": "5.2.9",
334
+ "v8-export-import/references/progressive-03-安全-性能注意.md": "5.2.9",
335
+ "v8-file-upload/SKILL.md": "5.2.9",
336
+ "v8-file-upload/references/progressive-01-公有桶-vs-私有桶.md": "5.2.9",
337
+ "v8-file-upload/references/progressive-02-office-文件在线编辑版本号规则.md": "5.2.9",
338
+ "v8-formengine-http/SKILL.md": "5.2.9",
339
+ "v8-frontend-events/SKILL.md": "5.2.9",
340
+ "v8-frontend-events/references/bluetooth-print-api.md": "5.2.9",
341
+ "v8-frontend-events/references/bluetooth-print.md": "5.2.9",
342
+ "v8-frontend-events/references/progressive-01-列表事件.md": "5.2.9",
343
+ "v8-http-integration/SKILL.md": "5.2.9",
344
+ "v8-http-integration/references/progressive-01-get-请求.md": "5.2.9",
345
+ "v8-http-integration/references/progressive-02-错误处理模式.md": "5.2.9",
346
+ "v8-image-processing/SKILL.md": "5.2.9",
347
+ "v8-image-processing/agents/openai.yaml": "5.2.9",
348
+ "v8-image-processing/references/api-reference.md": "5.2.9",
349
+ "v8-menu-buttons/SKILL.md": "5.2.9",
350
+ "v8-menu-buttons/references/progressive-01-2-按钮对象-schema.md": "5.2.9",
351
+ "v8-menu-buttons/references/progressive-02-8-模式-f-后台任务按钮-长任务.md": "5.2.9",
352
+ "v8-menu-buttons/references/progressive-03-10-反模式-避免.md": "5.2.9",
353
+ "v8-mongodb/SKILL.md": "5.2.9",
354
+ "v8-mq-mqtt/SKILL.md": "5.2.9",
355
+ "v8-mq-mqtt/references/mqtt-production.md": "5.2.9",
356
+ "v8-mq-mqtt/references/progressive-01-v8-mqtt-iot-物联网.md": "5.2.9",
357
+ "v8-mq-mqtt/scripts/check-mqtt-skill-coverage.mjs": "5.2.9",
358
+ "v8-saas-multi-tenant/SKILL.md": "5.2.9",
359
+ "v8-security/SKILL.md": "5.2.9",
360
+ "v8-security/references/progressive-01-2-权限校验.md": "5.2.9",
361
+ "v8-security/references/progressive-02-7-日志记录.md": "5.2.9",
362
+ "v8-sql-query/SKILL.md": "5.2.9",
363
+ "v8-table-event/SKILL.md": "5.2.9",
364
+ "v8-table-event/references/progressive-01-informv8-js-表单打开事件.md": "5.2.9",
365
+ "v8-table-event/references/progressive-02-前端事件名-v8-eventname-可能的值.md": "5.2.9",
366
+ "v8-tcp-integration/SKILL.md": "5.2.9",
367
+ "v8-tcp-integration/agents/openai.yaml": "5.2.9",
368
+ "v8-template-engine/SKILL.md": "5.2.9",
369
+ "v8-utilities/SKILL.md": "5.2.9",
370
+ "v8-utilities/references/client-api-index.md": "5.2.9",
371
+ "v8-utilities/references/platform-http-routes.md": "5.2.9",
372
+ "v8-utilities/references/server-api-index.md": "5.2.9",
373
+ "v8-workflow/SKILL.md": "5.2.9",
374
+ "v8-workflow/references/progressive-01-节点开始-v8-事件.md": "5.2.9",
375
+ "workspace-conventions/SKILL.md": "5.2.9",
376
+ "workspace-conventions/references/progressive-01-版本更新日志保护规则-强制.md": "5.2.9",
377
+ "workspace-conventions/references/progressive-02-microi-net-api-本地启动约定.md": "5.2.9",
378
+ "workspace-conventions/references/progressive-03-cli-与-ide-插件错版共存约定.md": "5.2.9"
379
379
  },
380
380
  "files": [
381
381
  ".microi-skills-version.json",
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "5.2.8",
2
+ "version": "5.2.9",
3
3
  "versionRule": "Microi version uses three numeric parts. Each publish increments the last part; when a part exceeds 9 it carries to the previous part: 1.0.9 -> 1.1.0, 1.9.9 -> 2.0.0.",
4
4
  "managedBy": "Microi.VSCode/bump-version.js",
5
- "updatedAt": "2026-08-25T00:13:51.528Z"
5
+ "updatedAt": "2026-08-25T02:17:40.843Z"
6
6
  }
@@ -105,10 +105,14 @@ await V8.Notification.MarkRead({ All: true });
105
105
 
106
106
  “消息通知”应用包必须包含 `mic_msgset`、`mic_msg_event_log`、`wx_tpl_msg`、`wx_mp`、`wx_mini_program` 五张结构资源,以及相关菜单、`msg_event`、`msg_internal_list`、`msg_internal_mark_read`、`platform-chat-system-message`、`platform-chat-runtime`、`platform-message-notification-custom-hook` 和必要索引。`wx_mp`、`wx_mini_program` 只交付物理表结构与表单字段元数据,不得携带数据集;否则既可能泄露真实公众号/小程序密钥,也会覆盖目标租户配置。`sys_user.WxMpId` 和 `wx_tpl_msg` 会读取 `wx_mp`,漏包会使 `/system/diy-user` 等无关页面在加载 Select 数据源时触发 `GetDiyFieldSqlData` 缺表错误。包内不得包含真实公众号 Token/AppSecret、用户接收人、OpenId、历史发送记录或租户专属 URL。先 `ValidateOnly`,再在全新或缺表目标租户真实安装,回读五张表、应用版本和依赖页面;结构校验不能替代真实安装验收。
107
107
 
108
+ 应用包中的 `sys_apiengine.Id` 是跨应用共享物理表的稳定主键,必须在全部官方应用范围内全局唯一;不能只检查单包内 Key/Id。发布前必须同时扫描全部官方包的 `Id` 与 `ApiEngineKey`,任一跨包重复都应阻断发布和离线包生成。
109
+
108
110
  系统聊天门面 `platform-chat-system-message`(`Managed`)完成平台超级管理员校验后,只转调本应用单一拥有的 `platform-chat-runtime`(`Managed`)。运行时统一编排 `PersistMessage / PersistSystemMessage / PersistAssistantMessage / GetHistoryAndMarkRead / GetUnreadCount / TouchContact / ListContacts / DeleteContact`;Hub/Controller 旧入口只保留 DiyToken 认证、SignalR 投递和 AI 流式协议,不得直连 MongoDB/FormEngine 复制业务。访问密钥会话、空 Token、伪造租户/发送人必须失败关闭。
109
111
 
110
112
  `platform-chat-runtime` 以 `V8.CurrentUser` / `V8.OsClient` 为唯一身份与租户事实源,对“租户 + 稳定 RequestId”生成确定性 Mongo `_id`;只有全部载荷哈希一致才复用旧记录。MongoDB 不参与 `V8.DbTrans`,因此消息/已读/联系人成功后即是已提交事实;SignalR、投影或 After Hook 失败必须保持 `Code=1` 并通过 `DataAppend.HookWarning` / `ProjectionWarnings` 告警,不得伪装未发生而引导盲目重试。调用 `V8.MongoDb.UptFormDataByWhere` / `DelFormDataByWhere` 时必须使用包含当前用户/权威资源边界的非空参数化 `_Where`,规则详见 `../v8-mongodb/SKILL.md`。
111
113
 
114
+ `platform-chat-runtime` 必须保持 `StopHttp=1`、`AllowAnonymous=0`。SignalR Hub 在 DiyToken 与租户核验后,通过宿主一次性可信协议作用域调用,并携带宿主生成的权威当前用户快照;V8 对 `_InvokeType=Client` 的调用必须先执行 `V8.Method.RequireManagedProtocolContext()` 原子消费。不得为修复 Hub 误报“禁止 HTTP 调用”而开放 `StopHttp`,也不得接受 Param 中的信任布尔值、用户或租户覆盖;接口引擎内部 `Server` 嵌套调用保持原有语义。
115
+
112
116
  租户个性化仅写入 `platform-message-notification-custom-hook`(`CreateIfMissing`),默认正文必须精确为 `return { Code : 1 };`。运行时在 `BeforeChatRuntime / AfterChatRuntime` 调用 Hook:Before 失败在 Mongo 写前阻断,After 失败只告警。Hook 只接收 `Stage`、`SourceApiEngineKey`、`Action`、`ActorUserId`、`PeerUserId`、`MessageId`、`MessageType`;正文、头像、OpenId、Token 与其它秘密不得进入租户扩展。三项接口的源码顶部都要保留官方恢复/租户不覆盖提示,并在包合同测试中逐字核对独立源码、包内副本、所有权策略和 HTTP/匿名开关。
113
117
 
114
118
  ## 最低验收
@@ -94,6 +94,7 @@
94
94
  | 两节点同时发送 | 唯一索引只有一个 claim 成功,两节点都不崩溃 |
95
95
  | 写入后节点退出 | 日志仍可查询;发送状态可审计、可补偿 |
96
96
  | SignalR/Redis 短故障 | 业务写入不回滚,客户端列表回读恢复 |
97
+ | SignalR Hub 调用聊天运行时 | `StopHttp=1` 保持关闭;仅固定 Key/租户/权威用户绑定的一次性宿主上下文可通过,V8 原子消费一次 |
97
98
  | 事务回滚 | 不产生实时通知,业务日志随事务回滚 |
98
99
  | 离线用户 | 下次打开通知中心能看到并标记已读 |
99
100
  | 越权读取/已读 | 其它用户 Id 无效,记录不改变 |
@@ -363,9 +363,9 @@ async function jsonRequest(path, options = {}) {
363
363
 
364
364
  async function loadSysConfig() {
365
365
  const resolved = runtime();
366
- const result = await jsonRequest('/api/FormEngine/GetSysConfig', {
366
+ const result = await jsonRequest(`/apiengine/platform-sys-config?OsClient=${encodeURIComponent(resolved.osClient)}`, {
367
367
  method: 'POST',
368
- headers: { 'Content-Type': 'application/json', osclient: resolved.osClient, did: V8.getDid() },
368
+ headers: { 'Content-Type': 'application/json', osclient: resolved.osClient, did: V8.getDid(), apiengine: '1' },
369
369
  body: JSON.stringify({ OsClient: resolved.osClient, _SearchEqual: { IsEnable: 1 } })
370
370
  });
371
371
  if (!result.body || Number(result.body.Code) !== 1) {
@@ -475,12 +475,13 @@ async function validateCachedLogin() {
475
475
  if (validatedSessionToken === token && authenticatedIdentity()) return cachedUser;
476
476
 
477
477
  const resolved = runtime();
478
- const result = await jsonRequest('/api/SysUser/GetCurrentUser', {
478
+ const result = await jsonRequest(`/apiengine/platform-current-user?OsClient=${encodeURIComponent(resolved.osClient)}`, {
479
479
  method: 'POST',
480
480
  headers: {
481
481
  'Content-Type': 'application/json',
482
482
  osclient: resolved.osClient,
483
483
  did: V8.getDid(),
484
+ apiengine: '1',
484
485
  Token: token,
485
486
  Authorization: `Bearer ${token}`
486
487
  },
@@ -76,7 +76,7 @@ Page 模式要特别注意:
76
76
  - 匿名公有存储场景只允许当前 `OsClient` 目录下的 `filePathName`;接口响应文件场景用 `fileUrl` 接收当前平台正式 `ApiBase`,或由同端口本地后端读取的 loopback `/apiengine/...`,并要求 URL 显式携带当前 `OsClient`。两种场景都拒绝私有文件、跨租户路径、路径穿越和任意第三方域名。
77
77
  - `fileUrl` 路径没有文件扩展名时必须同时传 `fileName` 或 `fileType`。组件先调用 `/api/HDFS/PrepareOfficePreviewFromUrl`,由后端严格校验当前平台、当前 `OsClient` 和单层 `/apiengine/{key}`,再把响应文件透明缓存到当前租户公有对象存储;OnlyOffice 使用返回的公网静态地址。开发环境 loopback 只允许同端口本地后端读取,不能简单替换 origin,也不能把该接口扩展成通用 URL 代理。
78
78
  - `canEdit` 不能直接作为授权结果。最终允许编辑必须同时满足有效登录态;匿名即使传 `canEdit=1` 也强制使用 OnlyOffice `mode:'view'` 和 `permissions.edit=false`。
79
- - 私有文件调用 `/api/HDFS/GetPrivateFileUrl` 时传 `ForOfficePreview:true`,让远程 OnlyOffice 使用租户公网 `ApiBase` 的审计代理地址,避免 `localhost` 导致“下载失败”。
79
+ - 私有文件调用 `/apiengine/platform-private-file-url` 时传 `ForOfficePreview:true` 和权威资源上下文,让远程 OnlyOffice 使用租户公网 `ApiBase` 的审计代理地址,避免 `localhost` 导致“下载失败”。
80
80
  - `layout/index.vue` 仅在“路由要求隐藏外壳且当前无有效登录用户”时隐藏 Sidebar/Navbar/TagsView;登录用户打开同一路由仍保留正常系统布局。
81
81
  - 不要把匿名路由简单加入全局白名单后跳过组件鉴权;过期 Token 要清理,公有文件校验失败必须停止创建 OnlyOffice 配置。
82
82
 
@@ -160,7 +160,7 @@ DiyCommon.FormEngine.AddFormData("table_name", { Field: "value" }, function (res
160
160
 
161
161
  文件同步、跨平台导入等需要登录另一套 Microi API 的前端工具,也必须复用同一验证码契约:
162
162
 
163
- - 用户填写远程 `ApiBase` 和 `OsClient` 后,先请求远程 `/api/FormEngine/GetSysConfig`,按 `isEnabledFlag(EnableCaptcha)` 判断是否需要验证码,不能先盲目调用登录接口。
163
+ - 用户填写远程 `ApiBase` 和 `OsClient` 后,先请求远程 `/apiengine/platform-sys-config?OsClient=<OsClient>`,并让 Query、`osclient` Header 与 Body 三处租户一致;按 `isEnabledFlag(EnableCaptcha)` 判断是否需要验证码,不能先盲目调用登录接口。
164
164
  - 需要验证码时,自动请求远程 `/api/Captcha/GetCaptcha?OsClient=<OsClient>`,读取响应头 `captchaid` 并显示验证码图片;用户输入后,远程 `/api/SysUser/login` 必须同时提交 `_CaptchaId/_CaptchaValue`。
165
165
  - 远程地址或租户变化时清空旧验证码和 Token;登录失败时刷新验证码。未开启验证码时不得显示验证码输入,也不得提交空验证码字段。
166
166
  - 远程响应头必须通过 CORS 暴露 `captchaid` 和 `authorization`;前端还应兼容登录响应体中的 Token,避免只依赖响应头。
@@ -78,7 +78,7 @@ SDK 或项目请求模块必须提供登录所需的系统配置和验证码薄
78
78
 
79
79
  要求:
80
80
  - 提供 `isEnabledFlag(value)` 或等价工具,统一判断 `Sys_Config.EnableCaptcha`。它必须把 `true`、`1`、`'true'`、`'1'` 识别为开启,把 `false`、`0`、`'false'`、`'0'`、空值识别为关闭。
81
- - 提供 `getSysConfig()`,内部调用 `V8.GetSysConfig(true)` 或 `/api/DiyTable/GetSysConfig`,并保持当前租户 `OsClient` 一致。
81
+ - 提供 `getSysConfig()`,内部调用 `V8.GetSysConfig(true)` 或 `/apiengine/platform-sys-config`,并保持 Query、Header、Body 中的当前租户 `OsClient` 一致。
82
82
  - 提供 `getCaptcha()`,内部调用 `GET /api/Captcha/GetCaptcha`,`responseType:'arraybuffer'`,从响应头读取 `captchaid`,返回 `{ CaptchaId, ImageSrc }`。
83
83
  - 提供账号登录封装时,只有在页面传入验证码时才追加 `_CaptchaId/_CaptchaValue`;不要在未开启验证码时提交空字段。
84
84
  - PC Vue、UniApp H5、微信小程序和 App 的账号密码登录都必须使用同一套验证码判断和登录参数契约。
@@ -84,7 +84,7 @@ description: Microi 移动端质量门禁,适用于 UniApp/H5/微信小程序
84
84
  PC 端、H5、App、微信小程序或任何自定义前端只要调用 `/api/SysUser/login`、`/api/SysUser/Login` 或 `V8.Login(param)`,都必须先读取 `Sys_Config` 的 `EnableCaptcha` 配置,并按配置决定是否展示和提交图形验证码。
85
85
 
86
86
  要求:
87
- - 启动登录页时调用 `/api/DiyTable/GetSysConfig` 或项目 SDK 的 `V8.GetSysConfig(true)`,读取当前租户启用状态。
87
+ - 启动登录页时调用 `/apiengine/platform-sys-config` 或项目 SDK 的 `V8.GetSysConfig(true)`,读取当前租户启用状态;旧 Controller 路由只作兼容转发。
88
88
  - `EnableCaptcha` 可能是 `1`、`true`、`'1'`、`'true'`,也可能是大小写不同的字符串。必须使用统一的 `isEnabledFlag(value)` 或等价函数判断,不能直接 `!!value`,否则字符串 `'0'` 会被误判为开启。
89
89
  - 开启验证码时,登录表单必须显示验证码输入框和验证码图片;验证码图片通过 `GET /api/Captcha/GetCaptcha` 获取,读取响应头 `captchaid`,提交登录时附加 `_CaptchaId` 和 `_CaptchaValue`。
90
90
  - 登录失败、验证码错误、网络错误后必须刷新验证码并清空验证码输入;验证码未填写时前端直接阻止提交并提示用户。
@@ -102,7 +102,7 @@
102
102
  ### 资源与隐私文件
103
103
 
104
104
  - 公开图片走 FileServer/CDN。
105
- - 私有图片必须先调用签名 URL,如 `/api/HDFS/GetPrivateFileUrl`。
105
+ - 私有图片必须先通过 `/apiengine/platform-private-file-url` 携带权威资源上下文换取短期签名 URL;签发失败时禁止回退裸路径。
106
106
  - 上传接口必须通用,不能在平台 HDFS 控制器写某项目“只允许支付凭证或实名认证图片”这类硬编码。
107
107
  - iOS Safari 上传后要验证表单字段不丢失,上传组件不能重置整张表单。
108
108
 
@@ -63,7 +63,7 @@ Microi 标准小程序必须采用“平台内核 + 版本化元数据 + Profile
63
63
  - 登录、接口引擎、FormEngine、上传等所有请求头必须做大小写不敏感去重;`osclient` 只能发送一个运行期值,例如 `demo`,禁止同时传 `OsClient` 与 `osclient` 导致网络面板出现 `demo, demo`。
64
64
  - 账号密码登录只有在同时拿到成功码、有效 token 和有效用户 `Id` 时才算成功。Microi 登录 token 可能在响应头 `authorization`,用户信息可能在响应体 `Data`;两者任一缺失都要清理 SDK token、本地用户缓存和 session。
65
65
  - 恢复本地会话时必须重新校验 token 和用户 `Id`,禁止出现页面显示 `admin` 但状态仍是“未登录”的半登录状态。
66
- - 账号密码登录调用 `/api/SysUser/login`、`/api/SysUser/Login` 或 `V8.Login(param)` 前,必须读取 `/api/DiyTable/GetSysConfig` 或 `V8.GetSysConfig(true)`,并根据 `Sys_Config.EnableCaptcha` 决定是否显示图形验证码。判断函数必须兼容 `1`、`true`、`'1'`、`'true'`,不要直接 `!!cfg.EnableCaptcha`。
66
+ - 账号密码登录调用 `/api/SysUser/login`、`/api/SysUser/Login` 或 `V8.Login(param)` 前,必须读取 `/apiengine/platform-sys-config` 或 `V8.GetSysConfig(true)`,并根据 `Sys_Config.EnableCaptcha` 决定是否显示图形验证码。判断函数必须兼容 `1`、`true`、`'1'`、`'true'`,不要直接 `!!cfg.EnableCaptcha`。
67
67
  - 开启验证码时,页面必须通过 `GET /api/Captcha/GetCaptcha` 获取验证码图片,读取响应头 `captchaid`,提交账号登录时传 `_CaptchaId` 和 `_CaptchaValue`;登录失败后清空输入并刷新验证码。未开启验证码时不显示验证码,不传空验证码字段。
68
68
  - 微信小程序手机号快捷登录必须使用 `<button open-type="getPhoneNumber">`,通过 `@getphonenumber` 获取 `detail.code`,并重新调用 `uni.login({ provider:'weixin' })` 获取新的 `LoginCode`。前端不能假设能直接拿到手机号明文。
69
69
  - H5/App 可提供手机号输入兜底,但必须确认后端接口支持 `Phone` 登录;微信小程序优先走 `Code + LoginCode`。
@@ -209,13 +209,30 @@ function normalizeClientUploadPath(value) {
209
209
  return parts.join('/');
210
210
  }
211
211
 
212
- function normalizeFileUrlData(data, assetUrl, fallback = '') {
212
+ function normalizeFileUrlData(data, assetUrl, fallback = '') {
213
213
  const raw = Array.isArray(data) ? (data[0] || '') : (data || '');
214
214
  if (typeof raw === 'string') return assetUrl(raw || fallback);
215
215
  const url = raw.Url || raw.FileUrl || raw.FileURL || raw.PreviewUrl || raw.PreviewURL || raw.FullUrl || '';
216
216
  const path = raw.Path || raw.FilePathName || raw.FilePath || raw.FullPath || '';
217
217
  return assetUrl(url || path || fallback);
218
- }
218
+ }
219
+
220
+ function isLocalPackagedAsset(path) {
221
+ return /^(?:\.\/)?\/?static\//i.test(String(path || ''));
222
+ }
223
+
224
+ function hasPublicUploadFlag(value) {
225
+ if (!value || typeof value !== 'object') return false;
226
+ const raw = Array.isArray(value) ? (value[0] || {}) : value;
227
+ return raw.Limit === false || raw.Limit === 0 || String(raw.Limit).toLowerCase() === 'false' ||
228
+ raw.IsPrivate === false || raw.Private === false || raw.Public === true;
229
+ }
230
+
231
+ function isKnownPublicUploadPath(path) {
232
+ // Ordinary form uploads such as /xjy/img and /xjy/file are private by default.
233
+ // They must use the Managed signer instead of being mistaken for CDN assets.
234
+ return /^\/?(?:public|mci-public|xjy\/xjy\/miniapp-assets|xjy\/miniapp\/share)\//i.test(String(path || ''));
235
+ }
219
236
 
220
237
  function getHeaderValue(headers, key) {
221
238
  if (!headers) return '';
@@ -918,11 +935,12 @@ export function createMicroiV8(options = {}) {
918
935
  }
919
936
 
920
937
  // 资源地址统一过滤占位图,并兼容 HDFS 私有文件、FileServer 和绝对地址。
921
- function assetUrl(value) {
938
+ function assetUrl(value) {
922
939
  const picked = extractUploadPath(value);
923
940
  if (!picked || isBlockedAsset(picked)) return '';
924
941
  if (/^(https?:|data:|blob:|file:)/i.test(picked)) return picked;
925
- if (/^\/?file\//i.test(picked)) return joinUrl(config.apiBase, picked);
942
+ if (isLocalPackagedAsset(picked)) return picked;
943
+ if (/^\/?file\//i.test(picked)) return joinUrl(config.apiBase, picked);
926
944
  if (/^\//.test(picked) || /^[a-z0-9_-]+\//i.test(picked)) return joinUrl(config.fileServer || config.apiBase, picked);
927
945
  return picked;
928
946
  }
@@ -931,23 +949,59 @@ export function createMicroiV8(options = {}) {
931
949
  return config.blockedAssetPattern ? config.blockedAssetPattern.test(String(value || '')) : false;
932
950
  }
933
951
 
934
- async function resolveFileUrl(filePathName) {
935
- const path = extractUploadPath(filePathName);
936
- if (!path || isBlockedAsset(path)) return '';
937
- if (/^(https?:|blob:|data:|file:)/i.test(path)) return assetUrl(path);
938
-
939
- async function requestPrivate(action) {
940
- try {
941
- const body = await post(`/api/HDFS/${action}?FilePathName=${encodeURIComponent(path)}`, { OsClient: config.osClient }, {
942
- checkCode: false,
943
- silentError: true
944
- });
945
- if (body && body.Code === 1 && body.Data) return normalizeFileUrlData(body.Data, assetUrl, path);
952
+ function hasPrivateFileAccessContext(options = {}) {
953
+ const resourceKind = String(options.resourceKind || options.ResourceKind || 'FormField').trim();
954
+ const resourceId = String(options.resourceId || options.ResourceId || '').trim();
955
+ const formEngineKey = String(options.formEngineKey || options.FormEngineKey || '').trim();
956
+ const formDataId = String(options.formDataId || options.FormDataId || '').trim();
957
+ const fieldId = String(options.fieldId || options.FieldId || '').trim();
958
+ const sysMenuId = String(options.sysMenuId || options.SysMenuId || options.menuId || options.MenuId || '').trim();
959
+ const formFieldReady = Boolean(formEngineKey && formDataId && fieldId && sysMenuId);
960
+
961
+ if (resourceKind === 'UserAvatar' || resourceKind === 'MenuImportTemplate' || resourceKind === 'DeptImportTemplate') {
962
+ return Boolean(resourceId);
963
+ }
964
+ if (resourceKind === 'FileManagerObject') return Boolean(resourceId && sysMenuId);
965
+ if (resourceKind === 'FormFieldDerivedPreview') {
966
+ return formFieldReady && Boolean(options.originalFilePathName || options.OriginalFilePathName);
967
+ }
968
+ return resourceKind === 'FormField' && formFieldReady;
969
+ }
970
+
971
+ async function resolveFileUrl(filePathName, options = {}) {
972
+ const path = extractUploadPath(filePathName);
973
+ if (!path || isBlockedAsset(path)) return '';
974
+ if (/^(https?:|blob:|data:|file:)/i.test(path)) return assetUrl(path);
975
+ if (isLocalPackagedAsset(path) || options.private === false || hasPublicUploadFlag(filePathName) || isKnownPublicUploadPath(path)) {
976
+ return assetUrl(path);
977
+ }
978
+ // 私有对象没有权威资源上下文时直接失败关闭,禁止以裸路径换取签名。
979
+ if (!hasPrivateFileAccessContext(options)) return '';
980
+
981
+ async function requestPrivateFileUrl() {
982
+ try {
983
+ const body = await apiEngineRun('platform-private-file-url', {
984
+ OsClient: config.osClient,
985
+ FilePathName: path,
986
+ FormEngineKey: options.formEngineKey || options.FormEngineKey,
987
+ FormDataId: options.formDataId || options.FormDataId,
988
+ FieldId: options.fieldId || options.FieldId,
989
+ SysMenuId: options.sysMenuId || options.SysMenuId || options.menuId || options.MenuId,
990
+ ResourceKind: options.resourceKind || options.ResourceKind,
991
+ ResourceId: options.resourceId || options.ResourceId,
992
+ OriginalFilePathName: options.originalFilePathName || options.OriginalFilePathName,
993
+ _TableChildAuth: options.tableChildAuth || options._TableChildAuth,
994
+ HDFS: options.hdfs || options.HDFS
995
+ }, {
996
+ checkCode: false,
997
+ silentError: true
998
+ });
999
+ if (body && body.Code === 1 && body.Data) return normalizeFileUrlData(body.Data, assetUrl, path);
946
1000
  } catch (e) {}
947
1001
  return '';
948
1002
  }
949
1003
 
950
- return (await requestPrivate('GetPrivateFileUrl')) || (await requestPrivate('MallFileUrl')) || assetUrl(path);
1004
+ return (await requestPrivateFileUrl()) || '';
951
1005
  }
952
1006
 
953
1007
  // 文件上传同时支持 uni.uploadFile 与浏览器 fetch/FormData。
@@ -1237,7 +1291,7 @@ export function createMicroiV8(options = {}) {
1237
1291
 
1238
1292
  function legacyGetCurrentUser(refresh, callback) {
1239
1293
  if (refresh) {
1240
- legacyPost('/api/SysUser/getCurrentUser', {}, (result) => {
1294
+ legacyPost('/apiengine/platform-current-user', {}, (result) => {
1241
1295
  if (result && result.Code) legacySetCurrentUser(result.Data || {});
1242
1296
  if (typeof callback === 'function') callback(result);
1243
1297
  });
@@ -1484,7 +1538,7 @@ export function createMicroiV8(options = {}) {
1484
1538
  // 旧版前端 V8 依赖的后端接口路径,保留原名称以减少迁移成本。
1485
1539
  const legacyApi = {
1486
1540
  MicroiInit: '/apiengine/microi-init',
1487
- GetSysConfig: '/api/DiyTable/getSysConfig',
1541
+ GetSysConfig: '/apiengine/platform-sys-config',
1488
1542
  Login: '/api/SysUser/login',
1489
1543
  AddFormData: '/api/FormEngine/addFormData',
1490
1544
  AddFormDataBatch: '/api/FormEngine/addFormDataBatch',
@@ -1508,10 +1562,10 @@ export function createMicroiV8(options = {}) {
1508
1562
  UploadAnonymous: '/api/HDFS/uploadAnonymous',
1509
1563
  UniappUpload: '/api/HDFS/UniappUpload',
1510
1564
  UniappUploadAnonymous: '/api/HDFS/uniappUploadAnonymous',
1511
- GetCurrentUser: '/api/SysUser/getCurrentUser',
1565
+ GetCurrentUser: '/apiengine/platform-current-user',
1512
1566
  GetDateTimeNow: '/api/os/getDateTimeNow',
1513
1567
  AddSysLog: '/apiengine/platform-client-log',
1514
- GetOsClientByDomain: '/api/Os/getOsClientByDomain',
1568
+ GetOsClientByDomain: '/apiengine/platform-os-client-by-domain',
1515
1569
  ApiEngine: {}
1516
1570
  };
1517
1571
 
@@ -133,7 +133,7 @@ var url = V8.Method.GetPrivateFileUrl({
133
133
  // 后端审计代理 URL,过期不可访问;真实对象存储签名 URL 不会返回前端
134
134
  ```
135
135
 
136
- - 普通客户端调用 `/api/HDFS/GetPrivateFileUrl` 时,不能只提交 `FilePathName`,必须同时提交 `FormEngineKey`、`FormDataId`、`FieldId`、`SysMenuId`。服务端校验菜单、菜单绑定表、记录数据范围、字段归属以及字段值确实引用该路径后,才签发临时票据。
136
+ - 普通客户端调用 `/apiengine/platform-private-file-url` 时,不能只提交 `FilePathName`,必须同时提交 `FormEngineKey`、`FormDataId`、`FieldId`、`SysMenuId`。服务端校验菜单、菜单绑定表、记录数据范围、字段归属以及字段值确实引用该路径后,才签发临时票据;旧 Controller 路由仅作兼容转发,新代码禁止继续引用。
137
137
  - `FieldId` 必须属于目标表,且组件为 `FileUpload`、`ImgUpload` 或 `RichText`;`SysMenuId` 必须是当前用户真实拥有、并绑定目标表的菜单。RichText 还必须在真实 `img/video/source.src` 或 `a.href` 中精确引用请求路径,普通文字、`data-*` 和脚本标签不算授权依据。
138
138
  - 普通用户禁止通过该入口直接取得私有文件 `Byte` / `Stream`。签发失败时不能回退裸路径、真实对象存储签名地址或公有 URL。
139
139
  - 私有文件访问必须经过后端短期票据代理:签发链接时记录当前登录用户,实际 `GET/HEAD` 打开或下载时再记录一次访问行为;支持 `Range` 流式响应,并对同一次分片请求做短时去重,不能把文件完整读入内存。
@@ -17,7 +17,7 @@
17
17
 
18
18
  - OnlyOffice 文档服务器会在服务端再次下载文件。浏览器可以下载但 OnlyOffice 提示“下载失败”时,优先检查生成地址是否为 `localhost/127.0.0.1/内网域名`。
19
19
  - OnlyOffice 可能先对文档地址发起 `HEAD` 探测。响应文件接口除了 `GET 200`,还必须让 `HEAD` 返回相同的 `Content-Type/Content-Length/Content-Disposition`,不能返回 `405`。
20
- - 私有文件在线预览调用 `GetPrivateFileUrl` 或 `/api/HDFS/GetPrivateFileUrl` 时传 `ForOfficePreview:true`。审计代理应优先使用租户系统配置的公网 `ApiBase`,但仍把真实对象存储签名地址保存在共享 Redis ticket 中,禁止直接返回真实签名地址。
20
+ - 私有文件在线预览调用 `/apiengine/platform-private-file-url` 时传 `ForOfficePreview:true` 和权威资源上下文。审计代理应优先使用租户系统配置的公网 `ApiBase`,但仍把真实对象存储签名地址保存在共享 Redis ticket 中,禁止直接返回真实签名地址;旧 Controller 路由只作兼容转发。
21
21
  - `/online-office` 可以匿名访问。公有存储模式只允许当前 `OsClient` 目录下的 `filePathName`;接口模式通过 `fileUrl` 接收当前平台正式 `ApiBase`,或由同端口本地后端读取的 loopback `/apiengine/...` 响应文件地址,并要求 URL 显式携带当前 `OsClient`。两种模式都拒绝跨租户、路径穿越和任意第三方 URL;`isPrivate=1` 必须登录。
22
22
  - 匿名接口引擎预览不要求 V8 代码先上传 HDFS:接口开启【响应文件】和【允许匿名】后,完整地址 URL 编码传给 `fileUrl`,同时传 `fileName/fileType`。页面通过匿名安全中转让当前后端限域读取源文件,并以确定性路径缓存到当前租户公有对象存储;OnlyOffice 只接收公网 `FileServer` 地址。loopback 仅允许同端口本地后端访问,禁止开放任意 URL 代理。
23
23
  - `canEdit` 只是前端请求参数,不是权限。最终编辑条件必须是“有效登录态 && canEdit=true”;匿名始终只读,不能因 URL 参数放开编辑。
@@ -48,7 +48,7 @@
48
48
  | `GET /api/Captcha/getCaptcha` | 获取验证码图片;同时保存响应 `captchaid` |
49
49
  | `POST /api/Captcha/Recognize` | 受控验证码识别,主要供采集引擎 |
50
50
  | `POST /api/HDFS/Upload` | 受限文件上传;优先用平台 SDK/V8 Upload |
51
- | `POST /api/HDFS/GetPrivateFileUrl` | 获取当前租户短期私有文件地址 |
51
+ | `POST /apiengine/platform-private-file-url` | 获取当前租户短期私有文件地址;必须携带权威资源上下文 |
52
52
  | `GET /api/HDFS/OpenPrivateFile` | 受权打开私有文件/Office 代理 |
53
53
  | `POST /api/DiyChat/SendSystemMessage` | 发送站内消息;前端优先 `V8.SendSystemMessage` |
54
54
  | `POST /apiengine/platform-mq` | MQ 管理入口;Body 使用 `Action=Send`,仅当前租户超级管理员 |