@microi.net/cli 5.8.3 → 5.8.4

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.
@@ -5,13 +5,13 @@
5
5
  "url": "https://microi.net"
6
6
  },
7
7
  "description": "Microi吾码官方 AI 插件市场",
8
- "version": "5.8.3",
8
+ "version": "5.8.4",
9
9
  "plugins": [
10
10
  {
11
11
  "name": "microi",
12
12
  "source": ".",
13
13
  "description": "Microi吾码 AI 开发插件:服务器连接、Skills、MCP、V8 全量同步与低代码交付",
14
- "version": "5.8.3",
14
+ "version": "5.8.4",
15
15
  "strict": true
16
16
  }
17
17
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "microi",
3
- "version": "5.8.3",
3
+ "version": "5.8.4",
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.8.3",
3
+ "version": "5.8.4",
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.8.3",
8
+ "version": "5.8.4",
9
9
  "plugins": [
10
10
  {
11
11
  "name": "microi",
12
12
  "source": ".",
13
13
  "description": "Microi吾码 AI 开发插件:服务器连接、Skills、MCP、V8 全量同步与低代码交付",
14
- "version": "5.8.3",
14
+ "version": "5.8.4",
15
15
  "strict": true
16
16
  }
17
17
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "microi",
3
- "version": "5.8.3",
3
+ "version": "5.8.4",
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-10-06T22:27:12.122Z",
3
- "version": "5.8.3",
2
+ "builtAt": "2026-10-08T11:43:10.784Z",
3
+ "version": "5.8.4",
4
4
  "sourceProducts": [
5
5
  "vscode-extension",
6
6
  "microi-cli",
@@ -10,10 +10,10 @@
10
10
  "commands": 55,
11
11
  "skills": 68,
12
12
  "hashes": {
13
- "mcpServer": "10dea581d3a3b926efed77de7179708358c7b5e151137a639d4126645b64d269",
13
+ "mcpServer": "26c3e0d5375ea2a1e2f8334a9c40fbbba928521c27d25fd4e82db52c785d345d",
14
14
  "cli": "7dbc7a3364e6d1f884accfe0dc704f12b595bcd6ca20fbbf0f1fe51369bb4525",
15
15
  "router": "1cb624a05b38ea717601b4dc678426840fbd39220014fc5316f09f2e6b50f733",
16
16
  "broker": "e4f21ac938950af5a446a2f5f39acc6e6e73535eab6e644fac6e04e73c4069e9",
17
- "dshBundle": "ed13b2b50ab7ee1cf8c38e8518e98c2076f3a9319d135c1f79aaf6be03ea5a18"
17
+ "dshBundle": "2db7a65bca297b8c1264e83695f61964c6e8aabb25da71db58d0beb219aaef7f"
18
18
  }
19
19
  }
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.8.3';\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.8.4';\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.8.3",
3
+ "version": "5.8.4",
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",
@@ -610,7 +610,7 @@ ${JSON.stringify(u,null,2)}
610
610
  `,"| # | Title | Number | Description | Updated |","|---|-------|--------|-------------|---------|"];return c.forEach((u,p)=>{l.push(`| ${p+1} | ${u.Title||""} | ${u.Number||""} | ${u.Desc||""} | ${u.UpdateTime||""} |`)}),{content:[{type:"text",text:l.join(`
611
611
  `)}]}}catch(s){return{content:[{type:"text",text:`Error: ${s instanceof Error?s.message:String(s)}`}],isError:!0}}}),i.tool("microi_get_page",`Get page engine detail including full JSON configuration for OsClient "${r}". The JsonObj field contains the complete page structure with formData, wrapperList, and widgetList.`,{pageId:d.string().describe("The page Id to retrieve")},async({pageId:a})=>{try{let s=await t.getPageEngineDetail(a);if(s.Code!==1)return{content:[{type:"text",text:`Error: ${s.Msg}`}],isError:!0};let c=s.Data;return{content:[{type:"text",text:[`## Page: ${c?.Title||a}`,c?.Number?`- **Number**: ${c.Number}`:"",c?.Desc?`- **Description**: ${c.Desc}`:"","","### JSON Configuration","```json",typeof c?.JsonObj=="string"?c.JsonObj:JSON.stringify(c?.JsonObj,null,2),"```"].filter(Boolean).join(`
612
612
  `)}]}}catch(s){return{content:[{type:"text",text:`Error: ${s instanceof Error?s.message:String(s)}`}],isError:!0}}}),i.tool("microi_save_page",`Create or update a page engine page for OsClient "${r}". Accepts raw JsonObj, {JsonObj}, {JsonStr}, a mic_page row, or {formData:{JsonObj}} and normalizes it to the canonical JsonObj saved in mic_page.JsonObj. Pass pageId to update an existing page, or omit to create a new one.`,{pageId:d.string().optional().describe("Page Id to update. Omit to create a new page."),title:d.string().describe('Page title (e.g. "\u9500\u552E\u4EEA\u8868\u76D8", "\u6570\u636E\u6982\u89C8")'),number:d.string().optional().describe("Page number/code (auto-generated if omitted)"),desc:d.string().optional().describe("Page description"),jsonStr:d.string().optional().describe("Page Engine JsonObj string. Prefer json for object input."),json:d.unknown().optional().describe("Page Engine JSON object/string in any common AI output shape."),routePath:d.string().optional().describe("Optional route path saved to mic_page.RoutePath."),componentPath:d.string().optional().describe("Optional component path saved to mic_page.ComponentPath.")},async({pageId:a,title:s,number:c,desc:l,jsonStr:u,json:p,routePath:f,componentPath:m})=>{try{let h=ti(p??u);if(!h.ok||!h.json)return{content:[{type:"text",text:JSON.stringify(h,null,2)}],isError:!0};let g=await t.savePageEngine({PageId:a,Title:s,Number:c,Desc:l,JsonStr:h.json,RoutePath:f,ComponentPath:m});if(g.Code!==1)return{content:[{type:"text",text:`Error: ${g.Msg}`}],isError:!0};let y=g.Data;return{content:[{type:"text",text:`\u2705 ${y?.Message||"Page saved successfully."}
613
- - PageId: ${y?.PageId}`}]}}catch(h){return{content:[{type:"text",text:`Error: ${h instanceof Error?h.message:String(h)}`}],isError:!0}}}),i.tool("microi_list_applications",`List every online AI application for OsClient "${r}" across Web, UniApp and MicroService, including each app's complete source-file manifest by default. AI agents should call this at the beginning of application/page work so they understand existing apps before creating duplicates. For complex custom dialogs/pages, prefer extending an existing MicroService or creating one with microi_create_microservice + microi_sync_microservice_source; do not embed large HTML in V8.ConfirmTips.`,{appType:d.enum(["Web","UniApp","MicroService"]).optional().describe("Optional exact application type filter."),keyword:d.string().optional().describe("Optional case-insensitive search across name, AppKey, type and description."),includeFiles:d.boolean().optional().default(!0).describe("Include the complete file manifest for every app. Defaults to true.")},async({appType:a,keyword:s,includeFiles:c})=>{try{let l=await t.listApplications({AppType:a,Keyword:s,IncludeFiles:c!==!1});return l.Code!==1?{content:[{type:"text",text:`Error: ${l.Msg}`}],isError:!0}:{content:[{type:"text",text:JSON.stringify(l.Data,null,2)}]}}catch(l){return{content:[{type:"text",text:`Error: ${l instanceof Error?l.message:String(l)}`}],isError:!0}}}),i.tool("microi_get_application_context",`Get one Web, UniApp or MicroService application by Id/AppKey for OsClient "${r}". It returns metadata and the full file manifest by default without embedding source bodies; set includeContents=true only when the complete source is actually needed, or use microi_get_application_file for one exact file. MicroService responses also include sys_microiservice runtime/pages.`,{appIdOrKey:d.string().describe("sys_microistore.Id or AppKey."),includeContents:d.boolean().optional().default(!1).describe("Read private HDFS source contents. Defaults to false; prefer microi_get_application_file for targeted reads."),maxFileBytes:d.number().int().positive().optional().describe("Maximum bytes read per source file. Default 2MB."),maxTotalBytes:d.number().int().positive().optional().describe("Maximum total bytes read for this app. Default 50MB.")},async({appIdOrKey:a,includeContents:s,maxFileBytes:c,maxTotalBytes:l})=>{try{let u=await t.getApplicationContext({AppIdOrKey:a,IncludeContents:s===!0,...c?{MaxFileBytes:c}:{},...l?{MaxTotalBytes:l}:{}});if(u.Code!==1)return{content:[{type:"text",text:`Error: ${u.Msg}`}],isError:!0};let p=u.Data,m=(Array.isArray(p?.Files)?p.Files:[]).filter(g=>typeof g?.ContentReadError=="string"&&g.ContentReadError).length,h={...p,McpReadSummary:{RequestedContents:s===!0,ContentsComplete:s!==!0||m===0,ContentErrorCount:m}};return{content:[{type:"text",text:JSON.stringify(h,null,2)}]}}catch(u){return{content:[{type:"text",text:`Error: ${u instanceof Error?u.message:String(u)}`}],isError:!0}}}),i.tool("microi_get_application_file",`Read one exact source file from a Web, UniApp or MicroService online AI application for OsClient "${r}". Text code is returned as UTF-8 Content; binary files are returned as FileByteBase64.`,{appIdOrKey:d.string().describe("sys_microistore.Id or AppKey."),filePath:d.string().describe("Exact relative source path from the application file manifest."),maxFileBytes:d.number().int().positive().optional().describe("Maximum bytes read. Default 10MB.")},async({appIdOrKey:a,filePath:s,maxFileBytes:c})=>{try{let l=await t.getApplicationFile({AppIdOrKey:a,FilePath:s,IncludeContents:!0,...c?{MaxFileBytes:c}:{}});return l.Code!==1?{content:[{type:"text",text:`Error: ${l.Msg}`}],isError:!0}:{content:[{type:"text",text:JSON.stringify(l.Data,null,2)}]}}catch(l){return{content:[{type:"text",text:`Error: ${l instanceof Error?l.message:String(l)}`}],isError:!0}}}),i.tool("microi_scaffold_vue_microservice",`Create a safe, maintainable MicroService scaffold for OsClient "${r}" using the stable Vue 3.5.40 + Vite 7.3.6 + TypeScript 5.9.3 baseline, @vitejs/plugin-vue 6.0.8, vue-tsc 3.3.9, Composition API and <script setup lang="ts">. The minimal template keeps Microi SDK and host/internal-route integration but does not force Pinia or Vue Router; add either only when application complexity needs it. It writes .microi-micro-app.json, microi.routes.json and exactly one Vue component per declared route inside the local tenant AI\u5E94\u7528 directory. It only accepts a real absolute directory whose basename is AI\u5E94\u7528, never overwrites a different existing project, and performs a dry run until confirmExecution exactly equals appKey. After scaffolding, run npm install and npm run build, then use microi_create_microservice, microi_sync_microservice_source and microi_publish_application_directory_stream (or the legacy publisher for a tiny compatibility payload).`,{appKey:d.string().regex(/^[a-z0-9](?:[a-z0-9_-]{0,62}[a-z0-9])?$/u).describe("Stable lowercase application key and local directory name."),name:d.string().min(1).max(120).describe("Human-readable MicroService name."),description:d.string().optional().describe("Optional application description."),aiApplicationsDirectory:d.string().optional().describe("Absolute tenant AI\u5E94\u7528 directory. Defaults to MICROI_AI_APPLICATIONS_DIR injected by Microi.Agent."),buildVersion:d.string().regex(/^v\d+\.\d+\.\d+$/u).optional().default("v0.1.0").describe("Initial semantic build version. Default v0.1.0."),routes:d.array(d.object({path:d.string().describe("Internal route path such as /context-test."),name:d.string().describe("Stable route key such as context-test."),title:d.string().describe("Page/menu title."),description:d.string().optional().describe("Optional visible page explanation."),isHome:d.boolean().optional().describe("Mark one route as the default page. The first route is used when omitted.")})).min(1).max(50).describe("Vue pages and MicroService internal routes. One .vue file is generated per item."),confirmExecution:d.string().optional().describe("Required for filesystem writes and must exactly equal appKey. Omit for a local preflight only.")},async({appKey:a,name:s,description:c,aiApplicationsDirectory:l,buildVersion:u,routes:p,confirmExecution:f})=>{try{let m=String(l||process.env.MICROI_AI_APPLICATIONS_DIR||"").trim();if(!m)return{content:[{type:"text",text:"Error: \u7F3A\u5C11 AI \u5E94\u7528\u76EE\u5F55\u3002\u8BF7\u7531 Microi.Agent \u6CE8\u5165 MICROI_AI_APPLICATIONS_DIR\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 aiApplicationsDirectory\u3002"}],isError:!0};if(f&&f!==a)return{content:[{type:"text",text:`Error: confirmExecution \u5FC5\u987B\u7CBE\u786E\u7B49\u4E8E ${a}`}],isError:!0};let h={aiApplicationsDirectory:m,appKey:a,name:s,description:c,apiBaseUrl:e.apiBaseUrl,osClient:r,buildVersion:u,routes:p,sdkSource:RO(process.env.MICROI_WORKSPACE_ROOT)},g=xw(h);if(f!==a)return{content:[{type:"text",text:JSON.stringify({dryRun:!0,confirmationRequired:a,targetDirectory:g.targetDirectory,appKey:g.appKey,buildVersion:g.buildVersion,routeCount:g.routes.length,routes:g.routes.map(x=>({path:x.path,name:x.name,title:x.title,sourceFile:x.sourceFile,isHome:x.isHome})),fileCount:g.files.length,files:g.files.map(x=>({Path:x.relativePath,Size:x.size,Sha256:x.sha256}))},null,2)}]};let y=PO(h);return{content:[{type:"text",text:JSON.stringify(y,null,2)}]}}catch(m){return{content:[{type:"text",text:`Error: ${m instanceof Error?m.message:String(m)}`}],isError:!0}}}),i.tool("microi_get_microservice",`Get one Microi microservice / micro-app by MsKey for OsClient "${r}". Use this before publishing to inspect current BuildVersion, EntryPath and asset manifest.`,{msKey:d.string().describe("Microservice key, stored in sys_microiservice.MsKey")},async({msKey:a})=>{try{let s=await t.getMicroService(a);return s.Code!==1?{content:[{type:"text",text:`Error: ${s.Msg}`}],isError:!0}:{content:[{type:"text",text:JSON.stringify(s.Data,null,2)}]}}catch(s){return{content:[{type:"text",text:`Error: ${s instanceof Error?s.message:String(s)}`}],isError:!0}}}),i.tool("microi_create_microservice",`Create or update sys_microiservice metadata for OsClient "${r}". This only writes metadata. For generated app source/dist files, use microi_publish_microservice.`,{microService:Nt.describe("Microservice metadata. Required: MsKey and MsName/Name. Optional: MsType, Runtime, StorageMode, SourceDirName, EntryPath, BuildVersion."),confirmExecution:d.string().optional().describe("Required for real writes. Pass any non-empty confirmation string after reviewing the payload.")},async({microService:a,confirmExecution:s})=>{if(!s)return{content:[{type:"text",text:JSON.stringify({dryRun:!0,microService:a},null,2)}]};try{let c=await t.createMicroService(a);return c.Code!==1?{content:[{type:"text",text:`Error: ${c.Msg}`}],isError:!0}:{content:[{type:"text",text:JSON.stringify(c.Data,null,2)}]}}catch(c){return{content:[{type:"text",text:`Error: ${c instanceof Error?c.message:String(c)}`}],isError:!0}}}),i.tool("microi_sync_microservice_source",`Sync a local Web, UniApp or MicroService source directory into the online AI Application for OsClient "${r}". Prefer directory: MCP detects SourceStreamPublish, streams each original file into the private staged prefix, then atomically finalizes the complete manifest with CurrentVersion/AppVersion/SourceManifestHash CAS. Transport failures are read back before any exact replay. Old servers use bounded legacy JSON only for at most 256 files and 8MiB. AI agents must never read large files into Base64, create .sync-seg-* files, create sync-source-files.json, or split one source file across tool calls.`,{microService:Nt.describe("Microservice metadata. Required: MsKey and MsName/Name. Optional: Description and SourceDirName."),directory:d.string().optional().describe("Preferred. Absolute local project directory; MCP reads it directly and excludes node_modules, dist, build, coverage, caches and VCS data."),sourceFiles:d.array(Nt).optional().describe("Legacy compatibility only. Do not construct this array from manually split files when a local directory is available."),replace:d.boolean().optional().describe("Complete directory sync defaults to exact private-source replacement. Explicit false is rejected by the stream protocol; public runtime/build rows are always preserved."),confirmExecution:d.string().optional().describe("Required for real writes. Pass any non-empty confirmation string after reviewing the payload.")},async({microService:a,directory:s,sourceFiles:c,replace:l,confirmExecution:u})=>Fte(t,{microService:a,directory:s,sourceFiles:c,replace:l,confirmExecution:u})),i.tool("microi_clear_application_source",`Remove an AI application's private HDFS source objects, private mci_ai_app_file rows, public SourceZip objects and source-delivery flags while preserving compiled runtime/build assets for OsClient "${r}". This is intentionally destructive and two-phase: first call without confirmExecution to obtain the exact target list and confirmationSha256, then pass that hash unchanged. Keep a verified local source checkout before executing.`,{appIdOrKey:d.string().min(1).describe("Exact AppId or AppKey. No wildcard or bulk deletion is supported."),confirmExecution:d.string().optional().describe("Exact confirmationSha256 returned by the backend dry run.")},async({appIdOrKey:a,confirmExecution:s})=>{try{let c=await t.clearApplicationSource({AppIdOrKey:a,...s?{ConfirmExecution:s}:{}});return{content:[{type:"text",text:JSON.stringify(c,null,2)}],structuredContent:c,...c.Code!==1?{isError:!0}:{}}}catch(c){return{content:[{type:"text",text:`Clear application source failed: ${c instanceof Error?c.message:String(c)}`}],isError:!0}}}),i.tool("microi_upload_application_asset_stream",`Stream one local built asset directly to the immutable HDFS version directory for OsClient "${r}". Protocol v3 uses durable HDFS multipart sessions with status readback and reconnect resume for ordinary files through multi-GiB installers; bytes are never encoded as Base64 and never enter Jint. This is a low-level primitive inside a frozen release contract; normally use microi_publish_application_directory_stream to upload and atomically promote a complete directory.`,{appIdOrKey:d.string().min(1).describe("Existing sys_microistore Id or AppKey."),versionNo:d.string().regex(/^v?\d+\.\d+\.\d+$/u).describe("Immutable semantic version, e.g. v1.2.3."),relativePath:d.string().min(1).describe("POSIX-style path inside the compiled output, e.g. assets/index-abcd.js."),localFilePath:d.string().min(1).describe("Absolute or workspace-relative path of one local ordinary file."),sha256:d.string().regex(/^[a-fA-F0-9]{64}$/u).optional().describe("Optional expected SHA-256. MCP computes and verifies it when omitted."),routes:d.array(Nt).optional().default([]).describe("Canonical v3 route snapshot input; missing routes are frozen explicitly as []."),routeSnapshotJson:d.string().max(1024*1024).optional().describe("Protocol v3 requires the exact recursive-key-sorted, array-order-preserving UTF-8 canonical JSON for routes."),routeSnapshotHash:d.string().regex(/^[a-f0-9]{64}$/u).optional().describe("Protocol v3 requires the lowercase SHA-256 of RouteSnapshotJson."),sourceManifestHash:d.string().regex(/^[a-fA-F0-9]{64}$/u).optional().describe("Protocol v3 source-manifest SHA-256 tying this asset to the release."),runtimeManifestHash:d.string().regex(/^[a-f0-9]{64}$/u).optional().describe("Protocol v3 exact runtime-manifest SHA-256 for the frozen release."),deliveryBatchId:d.string().min(8).max(50).optional().describe("Protocol v3 stable delivery batch id."),protocolVersion:d.literal(3).optional().describe("Enable durable v3 multipart/resume. All v3 release identity and CAS fields then become required."),expectedGateEpoch:d.string().regex(/^(0|[1-9]\d*)$/u).optional().describe("Protocol v3 gate epoch as a canonical decimal bigint string."),requestId:d.string().regex(/^[A-Za-z0-9._:-]{8,100}$/u).optional().describe("Protocol v3 stable release RequestId; every asset and stage/finalize replay must reuse it exactly."),requestFingerprint:d.string().regex(/^[a-f0-9]{64}$/u).optional().describe("Protocol v3 immutable release fingerprint."),expectedCurrentVersion:d.number().int().min(0).optional().describe("Protocol v3 application CurrentVersion baseline."),expectedAppVersion:d.string().nullable().optional().describe("Protocol v3 application AppVersion baseline; explicit null means empty."),expectedPublishFence:d.string().regex(/^(0|[1-9]\d*)$/u).optional().describe("Protocol v3 sys_microistore.PublishFence baseline."),expectedPublishRowVersion:d.string().regex(/^(0|[1-9]\d*)$/u).optional().describe("Protocol v3 sys_microistore.PublishRowVersion baseline."),expectedVersionRowVersion:d.string().regex(/^(0|[1-9]\d*)$/u).nullable().optional().describe("Protocol v3 target version RowVersion; explicit null means absent."),expectedActivePublishVersionId:d.string().min(1).nullable().optional().describe("Protocol v3 active version id baseline; explicit null means empty."),expectedCommittedPublishVersionId:d.string().min(1).nullable().optional().describe("Protocol v3 committed version id baseline; explicit null means empty."),timeoutMs:d.number().int().min(1e3).max(2*60*6e4).optional().describe("Per-file upload timeout. Default 30 minutes; maximum 2 hours."),confirmExecution:d.string().optional().describe("Required for the real upload and must exactly equal appIdOrKey.")},async a=>Bte(t,a)),i.tool("microi_publish_application_directory_stream",`Publish a real Web, UniApp or MicroService build directory for OsClient "${r}" using deterministic RequestId evidence. Protocol v3 automatically switches files above the legacy 128 MiB request boundary to durable HDFS multipart sessions with per-part SHA-256, status readback and reconnect resume; logical files such as 5 GiB installers never enter Base64/Jint or whole-file memory. publishMode=stage uploads immutable version assets only; finalize rebuilds the same local manifest and promotes it without uploading; stage-and-finalize keeps the original one-call flow. Paths, hashes, sizes, request ids, version preconditions and final manifest evidence are verified strictly. Old API nodes without the resumable endpoints fail closed for oversized assets. \u6807\u51C6stdio\u7684128MiB\u672A\u89E3\u6790JSON-RPC\u7F13\u51B2\u53EA\u627F\u8F7D\u5DE5\u5177\u53C2\u6570/\u56DE\u6267\uFF1B\u76EE\u5F55\u8D44\u4EA7\u7EE7\u7EED\u539F\u59CB\u5B57\u8282\u6D41\u4E0A\u4F20\uFF0C\u4E0D\u628A\u5927\u6587\u4EF6\u6216\u6E90\u7801ZIP\u585E\u5165Base64\u5DE5\u5177\u53C2\u6570\u3002`,{appIdOrKey:d.string().min(1).describe("Existing sys_microistore Id or AppKey."),versionNo:d.string().regex(/^v?\d+\.\d+\.\d+$/u).describe("Immutable semantic version, e.g. v1.2.3."),directory:d.string().min(1).describe("Local compiled output directory such as dist or unpackage/dist/build/h5."),entryPath:d.string().optional().default("index.html").describe("Entry file relative to directory. Default index.html."),routes:d.array(Nt).optional().default([]).describe("Canonical v3 route snapshot input; missing routes are frozen explicitly as []."),routeSnapshotJson:d.string().max(1024*1024).optional().describe("Protocol v3 requires the exact recursive-key-sorted, array-order-preserving UTF-8 canonical JSON for routes."),routeSnapshotHash:d.string().regex(/^[a-f0-9]{64}$/u).optional().describe("Protocol v3 requires the lowercase SHA-256 of RouteSnapshotJson."),changeSummary:d.string().max(2e3).optional().describe("Version change summary stored in mci_ai_app_version on first stage insert. Maximum 2000 characters; retries preserve the original summary."),sourceManifestHash:d.string().regex(/^[a-fA-F0-9]{64}$/u).optional().describe("Optional source-manifest SHA-256 returned by microi_sync_microservice_source, tying source and runtime to one delivery."),runtimeManifestHash:d.string().regex(/^[a-f0-9]{64}$/u).optional().describe("Protocol v3 requires the exact lowercase runtime-manifest SHA-256 computed during the local dry run."),deliveryBatchId:d.string().min(8).max(50).optional().describe("Optional stable delivery batch id (8-50 characters, matching the API and LastBuildTaskId). When omitted MCP derives a deterministic id from app/version/manifest so retries remain stable."),publishMode:d.enum(["stage","finalize","stage-and-finalize"]).optional().default("stage-and-finalize").describe("stage uploads immutable assets only; finalize submits the local manifest only; stage-and-finalize preserves the original one-call behavior."),verificationOnly:d.boolean().optional().default(!1).describe("Protocol v3 stage only: submit/read the same frozen verification task without uploading files again. Pending is not ReleaseVerified and never permits finalize."),protocolVersion:d.literal(3).optional().describe("Explicit protocol v3 gate. When set, publishMode must be explicit stage or finalize and every v3 precondition is required."),expectedGateEpoch:d.string().regex(/^(0|[1-9]\d*)$/u).optional().describe("Protocol v3 gate epoch as a canonical decimal bigint string."),requestId:d.string().regex(/^[A-Za-z0-9._:-]{8,100}$/u).optional().describe("Protocol v3 stable release RequestId; stage/finalize and all Pending replays must reuse it exactly."),requestFingerprint:d.string().regex(/^[a-f0-9]{64}$/u).optional().describe("Protocol v3 immutable release fingerprint."),expectedCurrentVersion:d.number().int().min(0).optional().describe("Required for finalize/stage-and-finalize and omitted only during stage. Must equal the application CurrentVersion read before staging."),expectedAppVersion:d.string().nullable().optional().describe("Application AppVersion baseline. Protocol v3 requires explicit string or null for both stage and finalize."),expectedPublishFence:d.string().regex(/^(0|[1-9]\d*)$/u).optional().describe("Protocol v3 sys_microistore.PublishFence canonical decimal bigint string."),expectedPublishRowVersion:d.string().regex(/^(0|[1-9]\d*)$/u).optional().describe("Protocol v3 sys_microistore.PublishRowVersion canonical decimal bigint string."),expectedVersionRowVersion:d.string().regex(/^(0|[1-9]\d*)$/u).nullable().optional().describe("Protocol v3 target mci_ai_app_version.RowVersion; explicit null means the row must not exist."),expectedActivePublishVersionId:d.string().min(1).nullable().optional().describe("Protocol v3 active version id baseline; explicit null means empty."),expectedCommittedPublishVersionId:d.string().min(1).nullable().optional().describe("Protocol v3 committed version id baseline; explicit null means empty."),includeSourceMaps:d.boolean().optional().default(!1).describe("Publish *.map source maps. Defaults to false to avoid source disclosure."),maxFiles:d.number().int().min(1).max(2e4).optional().describe("Safety cap checked before upload. Default and hard maximum 20,000."),maxTotalMegabytes:d.number().positive().max(Number.MAX_SAFE_INTEGER/(1024*1024)).optional().describe("Optional caller safety cap checked before upload. Omit for the platform maximum; 5 GiB and larger builds use resumable HDFS multipart."),timeoutMsPerFile:d.number().int().min(1e3).max(2*60*6e4).optional().describe("Per-file upload timeout. Default 30 minutes."),allowLegacyFallback:d.boolean().optional().default(!1).describe("Deprecated compatibility flag. RequestId-capable two-phase publishing fails closed on old API nodes instead of publishing through the legacy payload."),confirmExecution:d.string().optional().describe("Required for real publishing and must exactly equal appIdOrKey. Omit for a local preflight manifest only.")},async({appIdOrKey:a,versionNo:s,directory:c,entryPath:l,routes:u,routeSnapshotJson:p,routeSnapshotHash:f,changeSummary:m,sourceManifestHash:h,runtimeManifestHash:g,deliveryBatchId:y,publishMode:x,verificationOnly:b,protocolVersion:v,expectedGateEpoch:_,requestId:w,requestFingerprint:C,expectedCurrentVersion:E,expectedAppVersion:T,expectedPublishFence:A,expectedPublishRowVersion:I,expectedVersionRowVersion:R,expectedActivePublishVersionId:F,expectedCommittedPublishVersionId:z,includeSourceMaps:j,maxFiles:K,maxTotalMegabytes:ee,timeoutMsPerFile:_e,allowLegacyFallback:me,confirmExecution:Ht})=>Vte(t,{appIdOrKey:a,versionNo:s,directory:c,entryPath:l,routes:u,routeSnapshotJson:p,routeSnapshotHash:f,changeSummary:m,sourceManifestHash:h,runtimeManifestHash:g,deliveryBatchId:y,publishMode:x,verificationOnly:b,protocolVersion:v,expectedGateEpoch:_,requestId:w,requestFingerprint:C,expectedCurrentVersion:E,expectedAppVersion:T,expectedPublishFence:A,expectedPublishRowVersion:I,expectedVersionRowVersion:R,expectedActivePublishVersionId:F,expectedCommittedPublishVersionId:z,includeSourceMaps:j,maxFiles:K,maxTotalMegabytes:ee,timeoutMsPerFile:_e,allowLegacyFallback:me,confirmExecution:Ht})),i.tool("microi_publish_microservice","Legacy small-payload publisher for generated microservice / micro-app files in Base64. For real compiled directories or large assets, use microi_publish_application_directory_stream so bytes stream directly to HDFS and never enter JSON/Jint.",{microService:Nt.describe("Microservice metadata. Required: MsKey and MsName/Name. Optional: BuildVersion, EntryPath, SourceDirName."),assets:d.array(Nt).describe("Built asset files. Each item needs Path/RelativePath/FileName and FileByteBase64/ContentBase64. Mark the main HTML/JS entry with IsEntry=true or Entry=true."),routes:d.array(Nt).optional().describe("Optional route/page records for sys_microiservice_page. Fields: PageKey, PageName, PageTitle, RoutePath, EntryPath, SourceDirName, SourceFile, RouteMetaJson, Sort, IsHome."),sourceManifestHash:d.string().regex(/^[a-fA-F0-9]{64}$/u).optional().describe("Optional source-manifest SHA-256 returned by source sync."),deliveryBatchId:d.string().min(8).max(50).optional().describe("Optional stable delivery batch id (8-50 characters, matching the API and LastBuildTaskId). MCP generates one when omitted."),confirmExecution:d.string().optional().describe("Required for real writes. Pass any non-empty confirmation string after reviewing the payload.")},async({microService:a,assets:s,routes:c,sourceManifestHash:l,deliveryBatchId:u,confirmExecution:p})=>{if(!p)return{content:[{type:"text",text:JSON.stringify({dryRun:!0,microService:a,assetCount:s.length,routes:c||[]},null,2)}]};try{let f=await t.publishMicroService({microService:a,assets:s,routes:c||[],DeliveryBatchId:u||nt.default.randomUUID(),SourceManifestHash:l||""});if(f.Code!==1)return{content:[{type:"text",text:`Error: ${f.Msg}`}],isError:!0};let m=String(a.MsKey||a.MicroServiceKey||a.AppKey||"").trim(),h=m?await t.probeMicroAppEntry(m):{ok:!1,url:"",error:"Cannot probe runtime because MsKey is missing"};for(let y of[250,750,1500]){if(h.ok||!m)break;await new Promise(x=>setTimeout(x,y)),h=await t.probeMicroAppEntry(m)}let g={...f.Data&&typeof f.Data=="object"?f.Data:{},RuntimeProbe:h,PublishedButUnavailable:!h.ok,...h.ok?{}:{Warning:"\u53D1\u5E03\u5143\u6570\u636E\u548C\u8D44\u4EA7\u5199\u5165\u5DF2\u5B8C\u6210\uFF0C\u4F46\u7A33\u5B9A\u5165\u53E3\u4E0D\u53EF\u7528\u3002\u8BF7\u68C0\u67E5 API \u8282\u70B9\u5230\u79DF\u6237 HDFS/MinIO \u516C\u6709\u6876\u7684\u670D\u52A1\u7AEF\u8BFB\u53D6\u94FE\u8DEF\uFF1B\u4E0D\u8981\u65E0\u5224\u65AD\u91CD\u590D\u53D1\u5E03\u3002"}};return{content:[{type:"text",text:JSON.stringify(g,null,2)}],...h.ok?{}:{isError:!0}}}catch(f){return{content:[{type:"text",text:`Error: ${f instanceof Error?f.message:String(f)}`}],isError:!0}}}),U2(i,t,e),F2(i,t,e),z2(i,t,e),j2(i,t,e),V2(i,t,e),K4(i,t),o.flush(e.codexMode?["microi_codex"]:void 0),i}function nre(t){let e=t.trim();if(!e||!/^[A-Za-z0-9+/]+={0,2}$/.test(e)||e.length%4!==0)return"";let r=Buffer.from(e,"base64");return r.toString("base64").replace(/=+$/,"")!==e.replace(/=+$/,"")?"":r.toString("utf8")}function iN(t){let e=t.MICROI_LABEL_BASE64||"";if(e){let r=nre(e);if(r)return r}return t.MICROI_LABEL||""}function oN(t,e,r,n="",i=""){try{let o=JSON.parse(Kl.default.readFileSync(t,"utf-8")),a=String(e||"").replace(/\/+$/,""),s=xd(e,r,n,i),c=r?s.filter(u=>u!==a):s;return sd(c.map(u=>Ua(o[u])))||Ua(o[a])}catch{return}}function ire(t){let e=t.body,r=String(t.headers["content-type"]||"");if(typeof e=="string"){/^application\/json\b/i.test(r)||(t.headers["content-type"]="application/json");try{return JSON.parse(e)}catch{return e}}if(e&&typeof e=="object")return/^application\/json\b/i.test(r)||(t.headers["content-type"]="application/json"),e}async function ore(){let t={apiBaseUrl:(process.env.MICROI_API_URL||"").replace(/\/+$/,""),username:process.env.MICROI_USERNAME||"",password:process.env.MICROI_PASSWORD||"",osClient:process.env.MICROI_OS_CLIENT||"",osClientType:process.env.MICROI_OS_CLIENT_TYPE||"",osClientNetwork:process.env.MICROI_OS_CLIENT_NETWORK||"",rsaPublicKey:process.env.MICROI_RSA_PUBLIC_KEY||void 0,token:process.env.MICROI_TOKEN||void 0,workspaceCredentialFilePath:process.env.MICROI_WORKSPACE_CREDENTIAL_FILE||void 0,workspaceCredentialUsernameKey:process.env.MICROI_WORKSPACE_USERNAME_KEY||void 0,workspaceCredentialPasswordKey:process.env.MICROI_WORKSPACE_PASSWORD_KEY||void 0};/^https:\/\/(localhost|127\.0\.0\.1)(:\d+)?/i.test(t.apiBaseUrl)&&(process.env.NODE_TLS_REJECT_UNAUTHORIZED="0",console.error("[microi-mcp] Detected localhost HTTPS, disabled TLS certificate verification"));let e=process.env.MICROI_TOKEN_FILE;if(e){t.tokenFilePath=e,t.authRecoveryRequestDir=process.env.MICROI_AUTH_RECOVERY_DIR||void 0;let n=oN(e,t.apiBaseUrl,t.osClient||"",t.osClientType||"",t.osClientNetwork||"");n&&(t.token=n)}if((process.env.MCP_TRANSPORT||"stdio")==="sse")t.apiBaseUrl||(console.error("Missing required: MICROI_API_URL (Microi backend API URL)"),process.exit(1)),await sre(parseInt(process.env.MCP_PORT||"3000",10),t);else{t.apiBaseUrl||(console.error("Missing required: MICROI_API_URL"),process.exit(1));let n=!!t.workspaceCredentialFilePath&&!!t.workspaceCredentialUsernameKey&&!!t.workspaceCredentialPasswordKey&&Kl.default.existsSync(t.workspaceCredentialFilePath);!t.token&&(!t.username||!t.password)&&!n&&(console.error("Missing required environment variables:"),console.error(" MICROI_API_URL - Microi backend API URL (e.g. https://api.example.com)"),console.error(" MICROI_TOKEN_FILE - Token file path (preferred, auto-managed by VS Code extension)"),console.error(" MICROI_AUTH_RECOVERY_DIR - Optional credential-free VS Code recovery request directory"),console.error(" MICROI_WORKSPACE_CREDENTIAL_FILE - Optional Windows DPAPI workspace credential vault"),console.error(" MICROI_TOKEN - JWT token (fallback)"),console.error(" MICROI_USERNAME - Login username (fallback if no token)"),console.error(" MICROI_PASSWORD - Login password (fallback if no token)"),console.error("Optional:"),console.error(" MICROI_OS_CLIENT - OsClient identifier"),console.error(" MICROI_OS_CLIENT_TYPE - Optional OsClient type for exact transport/token identity"),console.error(" MICROI_OS_CLIENT_NETWORK - Optional OsClient network for exact transport/token identity"),process.exit(1));let i=new Kc(t);await i.login();let o={osClient:t.osClient||"",osClientType:t.osClientType||"",osClientNetwork:t.osClientNetwork||"",apiBaseUrl:t.apiBaseUrl,label:iN(process.env),codexMode:process.env.MICROI_CODEX_MODE==="1"},a=Cw(i,o);await are(a),e&&Kl.default.watchFile(e,{interval:5e3},()=>{let c=oN(e,t.apiBaseUrl,t.osClient||"",t.osClientType||"",t.osClientNetwork||"");c&&(i.updateToken(c),console.error("[microi-mcp] Token updated from file"))});let s=()=>{e&&Kl.default.unwatchFile(e),i.destroy(),process.exit(0)};process.on("SIGINT",s),process.on("SIGTERM",s)}}async function are(t){let e=new Bu(process.stdin,process.stdout,{maxBufferSize:134217728});await t.connect(e),console.error("[microi-mcp] Server started (stdio mode)")}async function sre(t,e){let r=(0,Kf.default)();r.use(Kf.default.json({type:["application/json","application/*+json"],limit:"4mb"})),r.use(Kf.default.text({type:["text/plain","application/json-rpc"],limit:"4mb"}));let n=new Map;r.get("/sse",async(o,a)=>{let s=o.headers["x-microi-username"]||e.username,c=o.headers["x-microi-password"]||e.password;if(!s||!c){a.status(401).json({error:"Authentication required",message:"Provide X-Microi-Username and X-Microi-Password in request headers, or set MICROI_USERNAME / MICROI_PASSWORD environment variables."});return}try{let l=HR(o.headers,e),u=l.osClient||"",p=new Kc({apiBaseUrl:e.apiBaseUrl,username:s,password:c,...l,rsaPublicKey:e.rsaPublicKey});await p.login();let f={osClient:u||"",osClientType:l.osClientType||"",osClientNetwork:l.osClientNetwork||"",apiBaseUrl:e.apiBaseUrl,label:""},m=Cw(p,f),h=new op("/messages",a);n.set(h.sessionId,{transport:h,client:p}),a.on("close",()=>{let g=n.get(h.sessionId);g&&(g.client.destroy(),n.delete(h.sessionId),console.error(`[microi-mcp] Session ${h.sessionId} disconnected (user: ${s})`))}),console.error(`[microi-mcp] New session ${h.sessionId} (user: ${s}, osClient: ${u||"default"})`),await m.connect(h)}catch(l){let u=l instanceof Error?l.message:String(l);console.error(`[microi-mcp] SSE auth failed (user: ${s}): ${u}`),a.headersSent||a.status(401).json({error:"Authentication failed",message:u})}}),r.post("/messages",async(o,a)=>{let s=o.query.sessionId,c=n.get(s);if(!c){a.status(404).json({error:"Session not found"});return}await c.transport.handlePostMessage(o,a,ire(o))}),r.get("/health",(o,a)=>{a.json({status:"ok",server:"microi-mcp-server",version:"1.0.0",activeSessions:n.size})});let i=()=>{for(let[o,a]of n)a.client.destroy(),n.delete(o);process.exit(0)};process.on("SIGINT",i),process.on("SIGTERM",i),r.listen(t,()=>{console.error(`[microi-mcp] Server started (SSE mode) on http://localhost:${t}`),console.error(`[microi-mcp] SSE endpoint: http://localhost:${t}/sse`),console.error(`[microi-mcp] Auth: ${e.username?"env defaults available":"headers required"}`)})}ore().catch(t=>{console.error("[microi-mcp] Fatal error:",t instanceof Error?t.message:t),process.exit(1)});
613
+ - PageId: ${y?.PageId}`}]}}catch(h){return{content:[{type:"text",text:`Error: ${h instanceof Error?h.message:String(h)}`}],isError:!0}}}),i.tool("microi_list_applications",`List every online AI application for OsClient "${r}" across Web, UniApp and MicroService, including each app's complete source-file manifest by default. AI agents should call this at the beginning of application/page work so they understand existing apps before creating duplicates. For complex custom dialogs/pages, prefer extending an existing MicroService or creating one with microi_create_microservice + microi_sync_microservice_source; do not embed large HTML in V8.ConfirmTips.`,{appType:d.enum(["Web","UniApp","MicroService"]).optional().describe("Optional exact application type filter."),keyword:d.string().optional().describe("Optional case-insensitive search across name, AppKey, type and description."),includeFiles:d.boolean().optional().default(!0).describe("Include the complete file manifest for every app. Defaults to true.")},async({appType:a,keyword:s,includeFiles:c})=>{try{let l=await t.listApplications({AppType:a,Keyword:s,IncludeFiles:c!==!1});return l.Code!==1?{content:[{type:"text",text:`Error: ${l.Msg}`}],isError:!0}:{content:[{type:"text",text:JSON.stringify(l.Data,null,2)}]}}catch(l){return{content:[{type:"text",text:`Error: ${l instanceof Error?l.message:String(l)}`}],isError:!0}}}),i.tool("microi_get_application_context",`Get one Web, UniApp or MicroService application by Id/AppKey for OsClient "${r}". It returns metadata and the full file manifest by default without embedding source bodies; set includeContents=true only when the complete source is actually needed, or use microi_get_application_file for one exact file. MicroService responses also include sys_microiservice runtime/pages.`,{appIdOrKey:d.string().describe("sys_microistore.Id or AppKey."),includeContents:d.boolean().optional().default(!1).describe("Read private HDFS source contents. Defaults to false; prefer microi_get_application_file for targeted reads."),maxFileBytes:d.number().int().positive().optional().describe("Maximum bytes read per source file. Default 2MB."),maxTotalBytes:d.number().int().positive().optional().describe("Maximum total bytes read for this app. Default 50MB.")},async({appIdOrKey:a,includeContents:s,maxFileBytes:c,maxTotalBytes:l})=>{try{let u=await t.getApplicationContext({AppIdOrKey:a,IncludeContents:s===!0,...c?{MaxFileBytes:c}:{},...l?{MaxTotalBytes:l}:{}});if(u.Code!==1)return{content:[{type:"text",text:`Error: ${u.Msg}`}],isError:!0};let p=u.Data,m=(Array.isArray(p?.Files)?p.Files:[]).filter(g=>typeof g?.ContentReadError=="string"&&g.ContentReadError).length,h={...p,McpReadSummary:{RequestedContents:s===!0,ContentsComplete:s!==!0||m===0,ContentErrorCount:m}};return{content:[{type:"text",text:JSON.stringify(h,null,2)}]}}catch(u){return{content:[{type:"text",text:`Error: ${u instanceof Error?u.message:String(u)}`}],isError:!0}}}),i.tool("microi_get_application_file",`Read one exact source file from a Web, UniApp or MicroService online AI application for OsClient "${r}". Text code is returned as UTF-8 Content; binary files are returned as FileByteBase64.`,{appIdOrKey:d.string().describe("sys_microistore.Id or AppKey."),filePath:d.string().describe("Exact relative source path from the application file manifest."),maxFileBytes:d.number().int().positive().optional().describe("Maximum bytes read. Default 10MB.")},async({appIdOrKey:a,filePath:s,maxFileBytes:c})=>{try{let l=await t.getApplicationFile({AppIdOrKey:a,FilePath:s,IncludeContents:!0,...c?{MaxFileBytes:c}:{}});return l.Code!==1?{content:[{type:"text",text:`Error: ${l.Msg}`}],isError:!0}:{content:[{type:"text",text:JSON.stringify(l.Data,null,2)}]}}catch(l){return{content:[{type:"text",text:`Error: ${l instanceof Error?l.message:String(l)}`}],isError:!0}}}),i.tool("microi_scaffold_vue_microservice",`Create a safe, maintainable MicroService scaffold for OsClient "${r}" using the stable Vue 3.5.40 + Vite 7.3.6 + TypeScript 5.9.3 baseline, @vitejs/plugin-vue 6.0.8, vue-tsc 3.3.9, Composition API and <script setup lang="ts">. The minimal template keeps Microi SDK and host/internal-route integration but does not force Pinia or Vue Router; add either only when application complexity needs it. It writes .microi-micro-app.json, microi.routes.json and exactly one Vue component per declared route inside the local tenant AI\u5E94\u7528 directory. It only accepts a real absolute directory whose basename is AI\u5E94\u7528, never overwrites a different existing project, and performs a dry run until confirmExecution exactly equals appKey. After scaffolding, run npm install and npm run build, then use microi_create_microservice, microi_sync_microservice_source and microi_publish_application_directory_stream (or the legacy publisher for a tiny compatibility payload).`,{appKey:d.string().regex(/^[a-z0-9](?:[a-z0-9_-]{0,62}[a-z0-9])?$/u).describe("Stable lowercase application key and local directory name."),name:d.string().min(1).max(120).describe("Human-readable MicroService name."),description:d.string().optional().describe("Optional application description."),aiApplicationsDirectory:d.string().optional().describe("Absolute tenant AI\u5E94\u7528 directory. Defaults to MICROI_AI_APPLICATIONS_DIR injected by Microi.Agent."),buildVersion:d.string().regex(/^v\d+\.\d+\.\d+$/u).optional().default("v0.1.0").describe("Initial semantic build version. Default v0.1.0."),routes:d.array(d.object({path:d.string().describe("Internal route path such as /context-test."),name:d.string().describe("Stable route key such as context-test."),title:d.string().describe("Page/menu title."),description:d.string().optional().describe("Optional visible page explanation."),isHome:d.boolean().optional().describe("Mark one route as the default page. The first route is used when omitted.")})).min(1).max(50).describe("Vue pages and MicroService internal routes. One .vue file is generated per item."),confirmExecution:d.string().optional().describe("Required for filesystem writes and must exactly equal appKey. Omit for a local preflight only.")},async({appKey:a,name:s,description:c,aiApplicationsDirectory:l,buildVersion:u,routes:p,confirmExecution:f})=>{try{let m=String(l||process.env.MICROI_AI_APPLICATIONS_DIR||"").trim();if(!m)return{content:[{type:"text",text:"Error: \u7F3A\u5C11 AI \u5E94\u7528\u76EE\u5F55\u3002\u8BF7\u7531 Microi.Agent \u6CE8\u5165 MICROI_AI_APPLICATIONS_DIR\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 aiApplicationsDirectory\u3002"}],isError:!0};if(f&&f!==a)return{content:[{type:"text",text:`Error: confirmExecution \u5FC5\u987B\u7CBE\u786E\u7B49\u4E8E ${a}`}],isError:!0};let h={aiApplicationsDirectory:m,appKey:a,name:s,description:c,apiBaseUrl:e.apiBaseUrl,osClient:r,buildVersion:u,routes:p,sdkSource:RO(process.env.MICROI_WORKSPACE_ROOT)},g=xw(h);if(f!==a)return{content:[{type:"text",text:JSON.stringify({dryRun:!0,confirmationRequired:a,targetDirectory:g.targetDirectory,appKey:g.appKey,buildVersion:g.buildVersion,routeCount:g.routes.length,routes:g.routes.map(x=>({path:x.path,name:x.name,title:x.title,sourceFile:x.sourceFile,isHome:x.isHome})),fileCount:g.files.length,files:g.files.map(x=>({Path:x.relativePath,Size:x.size,Sha256:x.sha256}))},null,2)}]};let y=PO(h);return{content:[{type:"text",text:JSON.stringify(y,null,2)}]}}catch(m){return{content:[{type:"text",text:`Error: ${m instanceof Error?m.message:String(m)}`}],isError:!0}}}),i.tool("microi_get_microservice",`Get one Microi microservice / micro-app by MsKey for OsClient "${r}". Use this before publishing to inspect current BuildVersion, EntryPath and asset manifest.`,{msKey:d.string().describe("Microservice key, stored in sys_microiservice.MsKey")},async({msKey:a})=>{try{let s=await t.getMicroService(a);return s.Code!==1?{content:[{type:"text",text:`Error: ${s.Msg}`}],isError:!0}:{content:[{type:"text",text:JSON.stringify(s.Data,null,2)}]}}catch(s){return{content:[{type:"text",text:`Error: ${s instanceof Error?s.message:String(s)}`}],isError:!0}}}),i.tool("microi_create_microservice",`Create or update sys_microiservice metadata for OsClient "${r}". This only writes metadata. For generated app source/dist files, use microi_publish_microservice.`,{microService:Nt.describe("Microservice metadata. Required: MsKey and MsName/Name. Optional: MsType, Runtime, StorageMode, SourceDirName, EntryPath, BuildVersion."),confirmExecution:d.string().optional().describe("Required for real writes. Pass any non-empty confirmation string after reviewing the payload.")},async({microService:a,confirmExecution:s})=>{if(!s)return{content:[{type:"text",text:JSON.stringify({dryRun:!0,microService:a},null,2)}]};try{let c=await t.createMicroService(a);return c.Code!==1?{content:[{type:"text",text:`Error: ${c.Msg}`}],isError:!0}:{content:[{type:"text",text:JSON.stringify(c.Data,null,2)}]}}catch(c){return{content:[{type:"text",text:`Error: ${c instanceof Error?c.message:String(c)}`}],isError:!0}}}),i.tool("microi_sync_microservice_source",`Sync a local Web, UniApp or MicroService source directory into the online AI Application for OsClient "${r}". Prefer directory: MCP detects SourceStreamPublish, streams each original file into the private staged prefix, then atomically finalizes the complete manifest with CurrentVersion/AppVersion/SourceManifestHash CAS. Transport failures are read back before any exact replay. Old servers use bounded legacy JSON only for at most 256 files and 8MiB. AI agents must never read large files into Base64, create .sync-seg-* files, create sync-source-files.json, or split one source file across tool calls.`,{microService:Nt.describe("Microservice metadata. Required: MsKey and MsName/Name. Optional: Description and SourceDirName."),directory:d.string().optional().describe("Preferred. Absolute local project directory; MCP reads it directly and excludes node_modules, dist, build, coverage, caches and VCS data."),sourceFiles:d.array(Nt).optional().describe("Legacy compatibility only. Do not construct this array from manually split files when a local directory is available."),replace:d.boolean().optional().describe("Complete directory sync defaults to exact private-source replacement. Explicit false is rejected by the stream protocol; public runtime/build rows are always preserved."),confirmExecution:d.string().optional().describe("Required for real writes. Pass any non-empty confirmation string after reviewing the payload.")},async({microService:a,directory:s,sourceFiles:c,replace:l,confirmExecution:u})=>Fte(t,{microService:a,directory:s,sourceFiles:c,replace:l,confirmExecution:u})),i.tool("microi_clear_application_source",`Remove an AI application's private HDFS source objects, private mci_ai_app_file rows, public SourceZip objects and source-delivery flags while preserving compiled runtime/build assets for OsClient "${r}". This is intentionally destructive and two-phase: first call without confirmExecution to obtain the exact target list and confirmationSha256, then pass that hash unchanged. Keep a verified local source checkout before executing.`,{appIdOrKey:d.string().min(1).describe("Exact AppId or AppKey. No wildcard or bulk deletion is supported."),confirmExecution:d.string().optional().describe("Exact confirmationSha256 returned by the backend dry run.")},async({appIdOrKey:a,confirmExecution:s})=>{try{let c=await t.clearApplicationSource({AppIdOrKey:a,...s?{ConfirmExecution:s}:{}});return{content:[{type:"text",text:JSON.stringify(c,null,2)}],structuredContent:c,...c.Code!==1?{isError:!0}:{}}}catch(c){return{content:[{type:"text",text:`Clear application source failed: ${c instanceof Error?c.message:String(c)}`}],isError:!0}}}),i.tool("microi_upload_application_asset_stream",`Stream one local built asset directly to the immutable HDFS version directory for OsClient "${r}". Protocol v3 uses durable HDFS multipart sessions with status readback and reconnect resume for ordinary files through multi-GiB installers; bytes are never encoded as Base64 and never enter Jint. This is a low-level primitive inside a frozen release contract; normally use microi_publish_application_directory_stream to upload and atomically promote a complete directory.`,{appIdOrKey:d.string().min(1).describe("Existing sys_microistore Id or AppKey."),versionNo:d.string().regex(/^v?\d+\.\d+\.\d+$/u).describe("Immutable semantic version, e.g. v1.2.3."),relativePath:d.string().min(1).describe("POSIX-style path inside the compiled output, e.g. assets/index-abcd.js."),localFilePath:d.string().min(1).describe("Absolute or workspace-relative path of one local ordinary file."),sha256:d.string().regex(/^[a-fA-F0-9]{64}$/u).optional().describe("Optional expected SHA-256. MCP computes and verifies it when omitted."),routes:d.array(Nt).optional().default([]).describe("Canonical v3 route snapshot input; missing routes are frozen explicitly as []."),routeSnapshotJson:d.string().max(1024*1024).optional().describe("Protocol v3 requires the exact recursive-key-sorted, array-order-preserving UTF-8 canonical JSON for routes."),routeSnapshotHash:d.string().regex(/^[a-f0-9]{64}$/u).optional().describe("Protocol v3 requires the lowercase SHA-256 of RouteSnapshotJson."),sourceManifestHash:d.string().regex(/^[a-fA-F0-9]{64}$/u).optional().describe("Protocol v3 source-manifest SHA-256 tying this asset to the release."),runtimeManifestHash:d.string().regex(/^[a-f0-9]{64}$/u).optional().describe("Protocol v3 exact runtime-manifest SHA-256 for the frozen release."),deliveryBatchId:d.string().min(8).max(50).optional().describe("Protocol v3 stable delivery batch id."),protocolVersion:d.literal(3).optional().describe("Enable durable v3 multipart/resume. All v3 release identity and CAS fields then become required."),expectedGateEpoch:d.string().regex(/^(0|[1-9]\d*)$/u).optional().describe("Protocol v3 gate epoch as a canonical decimal bigint string."),requestId:d.string().regex(/^[A-Za-z0-9._:-]{8,100}$/u).optional().describe("Protocol v3 stable release RequestId; every asset and stage/finalize replay must reuse it exactly."),requestFingerprint:d.string().regex(/^[a-f0-9]{64}$/u).optional().describe("Protocol v3 immutable release fingerprint."),expectedCurrentVersion:d.number().int().min(0).optional().describe("Protocol v3 application CurrentVersion baseline."),expectedAppVersion:d.string().nullable().optional().describe("Protocol v3 application AppVersion baseline; explicit null means empty."),expectedPublishFence:d.string().regex(/^(0|[1-9]\d*)$/u).optional().describe("Protocol v3 sys_microistore.PublishFence baseline."),expectedPublishRowVersion:d.string().regex(/^(0|[1-9]\d*)$/u).optional().describe("Protocol v3 sys_microistore.PublishRowVersion baseline."),expectedVersionRowVersion:d.string().regex(/^(0|[1-9]\d*)$/u).nullable().optional().describe("Protocol v3 target version RowVersion; explicit null means absent."),expectedActivePublishVersionId:d.string().min(1).nullable().optional().describe("Protocol v3 active version id baseline; explicit null means empty."),expectedCommittedPublishVersionId:d.string().min(1).nullable().optional().describe("Protocol v3 committed version id baseline; explicit null means empty."),timeoutMs:d.number().int().min(1e3).max(2*60*6e4).optional().describe("Per-file upload timeout. Default 30 minutes; maximum 2 hours."),confirmExecution:d.string().optional().describe("Required for the real upload and must exactly equal appIdOrKey.")},async a=>Bte(t,a)),i.tool("microi_publish_application_directory_stream",`Publish a real Web, UniApp or MicroService build directory for OsClient "${r}" using deterministic RequestId evidence. Protocol v3 automatically switches files above the legacy 128 MiB request boundary to durable HDFS multipart sessions with per-part SHA-256, status readback and reconnect resume; logical files such as 5 GiB installers never enter Base64/Jint or whole-file memory. publishMode=stage uploads immutable version assets only; finalize rebuilds the same local manifest and promotes it without uploading; stage-and-finalize keeps the original one-call flow. Paths, hashes, sizes, request ids, version preconditions and final manifest evidence are verified strictly. Old API nodes without the resumable endpoints fail closed for oversized assets. \u6807\u51C6stdio\u7684128MiB\u672A\u89E3\u6790JSON-RPC\u7F13\u51B2\u53EA\u627F\u8F7D\u5DE5\u5177\u53C2\u6570/\u56DE\u6267\uFF1B\u76EE\u5F55\u8D44\u4EA7\u7EE7\u7EED\u539F\u59CB\u5B57\u8282\u6D41\u4E0A\u4F20\uFF0C\u4E0D\u628A\u5927\u6587\u4EF6\u6216\u6E90\u7801ZIP\u585E\u5165Base64\u5DE5\u5177\u53C2\u6570\u3002`,{appIdOrKey:d.string().min(1).describe("Existing sys_microistore Id or AppKey."),versionNo:d.string().regex(/^v?\d+\.\d+\.\d+$/u).describe("Immutable semantic version, e.g. v1.2.3."),directory:d.string().min(1).describe("Local compiled output directory such as dist or unpackage/dist/build/h5."),entryPath:d.string().optional().default("index.html").describe("Entry file relative to directory. Default index.html."),routes:d.array(Nt).optional().default([]).describe("Canonical v3 route snapshot input; missing routes are frozen explicitly as []."),routeSnapshotJson:d.string().max(1024*1024).optional().describe("Protocol v3 requires the exact recursive-key-sorted, array-order-preserving UTF-8 canonical JSON for routes."),routeSnapshotHash:d.string().regex(/^[a-f0-9]{64}$/u).optional().describe("Protocol v3 requires the lowercase SHA-256 of RouteSnapshotJson."),changeSummary:d.string().max(2e3).optional().describe("Version change summary stored in mci_ai_app_version on first stage insert. Maximum 2000 characters; retries preserve the original summary."),sourceManifestHash:d.string().regex(/^[a-fA-F0-9]{64}$/u).optional().describe("Optional source-manifest SHA-256 returned by microi_sync_microservice_source, tying source and runtime to one delivery."),runtimeManifestHash:d.string().regex(/^[a-f0-9]{64}$/u).optional().describe("Protocol v3 requires the exact lowercase runtime-manifest SHA-256 computed during the local dry run."),deliveryBatchId:d.string().min(8).max(50).optional().describe("Optional stable delivery batch id (8-50 characters, matching the API and LastBuildTaskId). When omitted MCP derives a deterministic id from app/version/manifest so retries remain stable."),publishMode:d.enum(["stage","finalize","stage-and-finalize"]).optional().default("stage-and-finalize").describe("stage uploads immutable assets only; finalize submits the local manifest only; stage-and-finalize preserves the original one-call behavior."),verificationOnly:d.boolean().optional().default(!1).describe("Protocol v3 stage only: submit/read the same frozen verification task without uploading files again. Pending is not ReleaseVerified and never permits finalize."),protocolVersion:d.literal(3).optional().describe("Explicit protocol v3 gate. When set, publishMode must be explicit stage or finalize and every v3 precondition is required."),expectedGateEpoch:d.string().regex(/^(0|[1-9]\d*)$/u).optional().describe("Protocol v3 gate epoch as a canonical decimal bigint string."),requestId:d.string().regex(/^[A-Za-z0-9._:-]{8,100}$/u).optional().describe("Protocol v3 stable release RequestId; stage/finalize and all Pending replays must reuse it exactly."),requestFingerprint:d.string().regex(/^[a-f0-9]{64}$/u).optional().describe("Protocol v3 immutable release fingerprint."),expectedCurrentVersion:d.number().int().min(0).optional().describe("Required for finalize/stage-and-finalize and omitted only during stage. Must equal the application CurrentVersion read before staging."),expectedAppVersion:d.string().nullable().optional().describe("Application AppVersion baseline. Protocol v3 requires explicit string or null for both stage and finalize."),expectedPublishFence:d.string().regex(/^(0|[1-9]\d*)$/u).optional().describe("Protocol v3 sys_microistore.PublishFence canonical decimal bigint string."),expectedPublishRowVersion:d.string().regex(/^(0|[1-9]\d*)$/u).optional().describe("Protocol v3 sys_microistore.PublishRowVersion canonical decimal bigint string."),expectedVersionRowVersion:d.string().regex(/^(0|[1-9]\d*)$/u).nullable().optional().describe("Protocol v3 target mci_ai_app_version.RowVersion; explicit null means the row must not exist."),expectedActivePublishVersionId:d.string().min(1).nullable().optional().describe("Protocol v3 active version id baseline; explicit null means empty."),expectedCommittedPublishVersionId:d.string().min(1).nullable().optional().describe("Protocol v3 committed version id baseline; explicit null means empty."),includeSourceMaps:d.boolean().optional().default(!1).describe("Publish *.map source maps. Defaults to false to avoid source disclosure."),maxFiles:d.number().int().min(1).max(2e4).optional().describe("Safety cap checked before upload. Default and hard maximum 20,000."),maxTotalMegabytes:d.number().positive().max(Number.MAX_SAFE_INTEGER/(1024*1024)).optional().describe("Optional caller safety cap checked before upload. Omit for the platform maximum; 5 GiB and larger builds use resumable HDFS multipart."),timeoutMsPerFile:d.number().int().min(1e3).max(2*60*6e4).optional().describe("Per-file upload timeout. Default 30 minutes."),allowLegacyFallback:d.boolean().optional().default(!1).describe("Deprecated compatibility flag. RequestId-capable two-phase publishing fails closed on old API nodes instead of publishing through the legacy payload."),confirmExecution:d.string().optional().describe("Required for real publishing and must exactly equal appIdOrKey. Omit for a local preflight manifest only.")},async({appIdOrKey:a,versionNo:s,directory:c,entryPath:l,routes:u,routeSnapshotJson:p,routeSnapshotHash:f,changeSummary:m,sourceManifestHash:h,runtimeManifestHash:g,deliveryBatchId:y,publishMode:x,verificationOnly:b,protocolVersion:v,expectedGateEpoch:_,requestId:w,requestFingerprint:C,expectedCurrentVersion:E,expectedAppVersion:T,expectedPublishFence:A,expectedPublishRowVersion:I,expectedVersionRowVersion:R,expectedActivePublishVersionId:F,expectedCommittedPublishVersionId:z,includeSourceMaps:j,maxFiles:K,maxTotalMegabytes:ee,timeoutMsPerFile:_e,allowLegacyFallback:me,confirmExecution:Ht})=>Vte(t,{appIdOrKey:a,versionNo:s,directory:c,entryPath:l,routes:u,routeSnapshotJson:p,routeSnapshotHash:f,changeSummary:m,sourceManifestHash:h,runtimeManifestHash:g,deliveryBatchId:y,publishMode:x,verificationOnly:b,protocolVersion:v,expectedGateEpoch:_,requestId:w,requestFingerprint:C,expectedCurrentVersion:E,expectedAppVersion:T,expectedPublishFence:A,expectedPublishRowVersion:I,expectedVersionRowVersion:R,expectedActivePublishVersionId:F,expectedCommittedPublishVersionId:z,includeSourceMaps:j,maxFiles:K,maxTotalMegabytes:ee,timeoutMsPerFile:_e,allowLegacyFallback:me,confirmExecution:Ht})),i.tool("microi_publish_microservice","Legacy small-payload publisher for generated microservice / micro-app files in Base64. For real compiled directories or large assets, use microi_publish_application_directory_stream so bytes stream directly to HDFS and never enter JSON/Jint.",{microService:Nt.describe("Microservice metadata. Required: MsKey and MsName/Name. Optional: BuildVersion, EntryPath, SourceDirName."),assets:d.array(Nt).describe("Built asset files. Each item needs Path/RelativePath/FileName and FileByteBase64/ContentBase64. Mark the main HTML/JS entry with IsEntry=true or Entry=true."),routes:d.array(Nt).optional().describe("Optional route/page records for sys_microiservice_page. Fields: PageKey, PageName, PageTitle, RoutePath, EntryPath, SourceDirName, SourceFile, RouteMetaJson, Sort, IsHome."),sourceManifestHash:d.string().regex(/^[a-fA-F0-9]{64}$/u).optional().describe("Optional source-manifest SHA-256 returned by source sync."),deliveryBatchId:d.string().min(8).max(50).optional().describe("Optional stable delivery batch id (8-50 characters, matching the API and LastBuildTaskId). MCP generates one when omitted."),confirmExecution:d.string().optional().describe("Required for real writes. Pass any non-empty confirmation string after reviewing the payload.")},async({microService:a,assets:s,routes:c,sourceManifestHash:l,deliveryBatchId:u,confirmExecution:p})=>{if(!p)return{content:[{type:"text",text:JSON.stringify({dryRun:!0,microService:a,assetCount:s.length,routes:c||[]},null,2)}]};try{let f=await t.publishMicroService({microService:a,assets:s,routes:c||[],DeliveryBatchId:u||nt.default.randomUUID(),SourceManifestHash:l||""});if(f.Code!==1)return{content:[{type:"text",text:`Error: ${f.Msg}`}],isError:!0};let m=String(a.MsKey||a.MicroServiceKey||a.AppKey||"").trim(),h=m?await t.probeMicroAppEntry(m):{ok:!1,url:"",error:"Cannot probe runtime because MsKey is missing"};for(let y of[250,750,1500]){if(h.ok||!m)break;await new Promise(x=>setTimeout(x,y)),h=await t.probeMicroAppEntry(m)}let g={...f.Data&&typeof f.Data=="object"?f.Data:{},RuntimeProbe:h,PublishedButUnavailable:!h.ok,...h.ok?{}:{Warning:"\u53D1\u5E03\u5143\u6570\u636E\u548C\u8D44\u4EA7\u5199\u5165\u5DF2\u5B8C\u6210\uFF0C\u4F46\u7A33\u5B9A\u5165\u53E3\u4E0D\u53EF\u7528\u3002\u8BF7\u68C0\u67E5 API \u8282\u70B9\u5230\u79DF\u6237 HDFS/MinIO \u516C\u6709\u6876\u7684\u670D\u52A1\u7AEF\u8BFB\u53D6\u94FE\u8DEF\uFF1B\u4E0D\u8981\u65E0\u5224\u65AD\u91CD\u590D\u53D1\u5E03\u3002"}};return{content:[{type:"text",text:JSON.stringify(g,null,2)}],...h.ok?{}:{isError:!0}}}catch(f){return{content:[{type:"text",text:`Error: ${f instanceof Error?f.message:String(f)}`}],isError:!0}}}),U2(i,t,e),F2(i,t,e),z2(i,t,e),j2(i,t,e),V2(i,t,e),K4(i,t),o.flush(e.codexMode?["microi_codex"]:void 0),i}function nre(t){let e=t.trim();if(!e||!/^[A-Za-z0-9+/]+={0,2}$/.test(e)||e.length%4!==0)return"";let r=Buffer.from(e,"base64");return r.toString("base64").replace(/=+$/,"")!==e.replace(/=+$/,"")?"":r.toString("utf8")}function iN(t){let e=t.MICROI_LABEL_BASE64||"";if(e){let r=nre(e);if(r)return r}return t.MICROI_LABEL||""}function oN(t,e,r,n="",i=""){try{let o=JSON.parse(Kl.default.readFileSync(t,"utf-8")),a=String(e||"").replace(/\/+$/,""),s=xd(e,r,n,i),c=r?s.filter(u=>u!==a):s;return sd(c.map(u=>Ua(o[u])))||Ua(o[a])}catch{return}}function ire(t){let e=t.body,r=String(t.headers["content-type"]||"");if(typeof e=="string"){/^application\/json\b/i.test(r)||(t.headers["content-type"]="application/json");try{return JSON.parse(e)}catch{return e}}if(e&&typeof e=="object")return/^application\/json\b/i.test(r)||(t.headers["content-type"]="application/json"),e}async function ore(){let t={apiBaseUrl:(process.env.MICROI_API_URL||"").replace(/\/+$/,""),username:process.env.MICROI_USERNAME||"",password:process.env.MICROI_PASSWORD||"",osClient:process.env.MICROI_OS_CLIENT||"",osClientType:process.env.MICROI_OS_CLIENT_TYPE||"",osClientNetwork:process.env.MICROI_OS_CLIENT_NETWORK||"",rsaPublicKey:process.env.MICROI_RSA_PUBLIC_KEY||void 0,token:process.env.MICROI_TOKEN||void 0,workspaceCredentialFilePath:process.env.MICROI_WORKSPACE_CREDENTIAL_FILE||void 0,workspaceCredentialUsernameKey:process.env.MICROI_WORKSPACE_USERNAME_KEY||void 0,workspaceCredentialPasswordKey:process.env.MICROI_WORKSPACE_PASSWORD_KEY||void 0},e=process.env.MICROI_TOKEN_FILE;if(e){t.tokenFilePath=e,t.authRecoveryRequestDir=process.env.MICROI_AUTH_RECOVERY_DIR||void 0;let n=oN(e,t.apiBaseUrl,t.osClient||"",t.osClientType||"",t.osClientNetwork||"");n&&(t.token=n)}if((process.env.MCP_TRANSPORT||"stdio")==="sse")t.apiBaseUrl||(console.error("Missing required: MICROI_API_URL (Microi backend API URL)"),process.exit(1)),await sre(parseInt(process.env.MCP_PORT||"3000",10),t);else{t.apiBaseUrl||(console.error("Missing required: MICROI_API_URL"),process.exit(1));let n=!!t.workspaceCredentialFilePath&&!!t.workspaceCredentialUsernameKey&&!!t.workspaceCredentialPasswordKey&&Kl.default.existsSync(t.workspaceCredentialFilePath);!t.token&&(!t.username||!t.password)&&!n&&(console.error("Missing required environment variables:"),console.error(" MICROI_API_URL - Microi backend API URL (e.g. https://api.example.com)"),console.error(" MICROI_TOKEN_FILE - Token file path (preferred, auto-managed by VS Code extension)"),console.error(" MICROI_AUTH_RECOVERY_DIR - Optional credential-free VS Code recovery request directory"),console.error(" MICROI_WORKSPACE_CREDENTIAL_FILE - Optional Windows DPAPI workspace credential vault"),console.error(" MICROI_TOKEN - JWT token (fallback)"),console.error(" MICROI_USERNAME - Login username (fallback if no token)"),console.error(" MICROI_PASSWORD - Login password (fallback if no token)"),console.error("Optional:"),console.error(" MICROI_OS_CLIENT - OsClient identifier"),console.error(" MICROI_OS_CLIENT_TYPE - Optional OsClient type for exact transport/token identity"),console.error(" MICROI_OS_CLIENT_NETWORK - Optional OsClient network for exact transport/token identity"),process.exit(1));let i=new Kc(t);await i.login();let o={osClient:t.osClient||"",osClientType:t.osClientType||"",osClientNetwork:t.osClientNetwork||"",apiBaseUrl:t.apiBaseUrl,label:iN(process.env),codexMode:process.env.MICROI_CODEX_MODE==="1"},a=Cw(i,o);await are(a),e&&Kl.default.watchFile(e,{interval:5e3},()=>{let c=oN(e,t.apiBaseUrl,t.osClient||"",t.osClientType||"",t.osClientNetwork||"");c&&(i.updateToken(c),console.error("[microi-mcp] Token updated from file"))});let s=()=>{e&&Kl.default.unwatchFile(e),i.destroy(),process.exit(0)};process.on("SIGINT",s),process.on("SIGTERM",s)}}async function are(t){let e=new Bu(process.stdin,process.stdout,{maxBufferSize:134217728});await t.connect(e),console.error("[microi-mcp] Server started (stdio mode)")}async function sre(t,e){let r=(0,Kf.default)();r.use(Kf.default.json({type:["application/json","application/*+json"],limit:"4mb"})),r.use(Kf.default.text({type:["text/plain","application/json-rpc"],limit:"4mb"}));let n=new Map;r.get("/sse",async(o,a)=>{let s=o.headers["x-microi-username"]||e.username,c=o.headers["x-microi-password"]||e.password;if(!s||!c){a.status(401).json({error:"Authentication required",message:"Provide X-Microi-Username and X-Microi-Password in request headers, or set MICROI_USERNAME / MICROI_PASSWORD environment variables."});return}try{let l=HR(o.headers,e),u=l.osClient||"",p=new Kc({apiBaseUrl:e.apiBaseUrl,username:s,password:c,...l,rsaPublicKey:e.rsaPublicKey});await p.login();let f={osClient:u||"",osClientType:l.osClientType||"",osClientNetwork:l.osClientNetwork||"",apiBaseUrl:e.apiBaseUrl,label:""},m=Cw(p,f),h=new op("/messages",a);n.set(h.sessionId,{transport:h,client:p}),a.on("close",()=>{let g=n.get(h.sessionId);g&&(g.client.destroy(),n.delete(h.sessionId),console.error(`[microi-mcp] Session ${h.sessionId} disconnected (user: ${s})`))}),console.error(`[microi-mcp] New session ${h.sessionId} (user: ${s}, osClient: ${u||"default"})`),await m.connect(h)}catch(l){let u=l instanceof Error?l.message:String(l);console.error(`[microi-mcp] SSE auth failed (user: ${s}): ${u}`),a.headersSent||a.status(401).json({error:"Authentication failed",message:u})}}),r.post("/messages",async(o,a)=>{let s=o.query.sessionId,c=n.get(s);if(!c){a.status(404).json({error:"Session not found"});return}await c.transport.handlePostMessage(o,a,ire(o))}),r.get("/health",(o,a)=>{a.json({status:"ok",server:"microi-mcp-server",version:"1.0.0",activeSessions:n.size})});let i=()=>{for(let[o,a]of n)a.client.destroy(),n.delete(o);process.exit(0)};process.on("SIGINT",i),process.on("SIGTERM",i),r.listen(t,()=>{console.error(`[microi-mcp] Server started (SSE mode) on http://localhost:${t}`),console.error(`[microi-mcp] SSE endpoint: http://localhost:${t}/sse`),console.error(`[microi-mcp] Auth: ${e.username?"env defaults available":"headers required"}`)})}ore().catch(t=>{console.error("[microi-mcp] Fatal error:",t instanceof Error?t.message:t),process.exit(1)});
614
614
  /*! Bundled license information:
615
615
 
616
616
  bytes/index.js:
@@ -1,13 +1,13 @@
1
1
  {
2
- "builtAt": "2026-10-07T02:29:18.187Z",
2
+ "builtAt": "2026-10-08T11:43:10.245Z",
3
3
  "source": "../microi.skills",
4
4
  "extension": {
5
5
  "name": "v8-engine",
6
- "version": "5.8.3",
6
+ "version": "5.8.4",
7
7
  "publisher": "Microi"
8
8
  },
9
9
  "skills": {
10
- "version": "5.8.3",
10
+ "version": "5.8.4",
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.Agent/bump-version.js"
13
13
  },
@@ -15,11 +15,11 @@
15
15
  "dir": "dist/microi.skills",
16
16
  "files": 190,
17
17
  "skills": 68,
18
- "bytes": 2673901
18
+ "bytes": 2680301
19
19
  },
20
20
  "fileHashes": {
21
- ".microi-skills-version.json": "d11f524a6201b3808a0ba1692e81f71f7e64e7313cd6a302713b6ea7e037aa01",
22
- ".progressive-disclosure-manifest.json": "dff998a43ff91cee1832cc26ae5e9bb74c8c4eb44d9f32a3d4085f54a285d9d4",
21
+ ".microi-skills-version.json": "9e90448790f59f0af7a6f195ae1f35ed712a808c10e5d85892380c0acb195433",
22
+ ".progressive-disclosure-manifest.json": "201a595502957f59ff666ff0b115cfd94e8dad442695642842ac5ae6c7d93f7b",
23
23
  "README.md": "a255a71542958918231b6da1a43b1f8fd6b1f8ea545274a233ef6d81c6239f0c",
24
24
  "ai-engine/SKILL.md": "ec3a0d88c33211ff066f8643c16090fa830eb9bcb56694d1c8e21eb2efd10bf0",
25
25
  "ai-engine/agents/openai.yaml": "6d6ff3e99f24e3390771ca448047a86ee2f611413ef3da3aaf11a31973d8965d",
@@ -27,7 +27,7 @@
27
27
  "ai-engine/references/self-hosted-digital-human.md": "8298c76b50807917430cdc69f57a5fe991b5dbba21d53e133db186064eba0638",
28
28
  "ai-platform-governance/SKILL.md": "84ca4bcacf15deecd0c04dc1a664b23041a6a5f020d3a5288c5458b5e7da4b8e",
29
29
  "ai-platform-governance/references/progressive-01-功能开关.md": "ea46fb02267e9e3ace3d9d72e67b02183c61e5c198f4b2f27e8196d6ee6d0bec",
30
- "app-store/SKILL.md": "2d06904ee4184207d67d6a742074d020b1eb89f5aef545e6f4f6643c14482604",
30
+ "app-store/SKILL.md": "557ab110a8f670a060f31cf5e52a4534c5514282e05d06c51414c81599ab4525",
31
31
  "app-store/agents/openai.yaml": "ac3354460d05778401f3150f5d814f3bb5b177594c99b07dd265a0aee1369eec",
32
32
  "business-blueprint/SKILL.md": "1cabd32404eff7e3c39bc3ac2e0c1cd498f9a9999f58cfc7d51cb37a0ef41a87",
33
33
  "datasource-engine/SKILL.md": "38762f001b4c5e3f604b9d418fa2665aae0a26083ebce147aa8f74a1550a5074",
@@ -51,7 +51,7 @@
51
51
  "microi-client-frontend/references/progressive-03-vue3-前端微服务宿主规则.md": "d37105bbaeb060e6b615f19739a5df7e43b531c266adffdb33be49d8504e146c",
52
52
  "microi-codex-installer/SKILL.md": "78e1d21845557c9c380aad3914dce2a38dc360b3bf5e93e36fbb7c9e957d8223",
53
53
  "microi-codex-installer/agents/openai.yaml": "e531219b74a70204893a156b1c22c69013a4c9d24b132ead912746b1b312cf80",
54
- "microi-codex/SKILL.md": "b91a946e6f23bb90023618a1d8eabecabfd55b0f30351f766f0d8bbd7c1f7217",
54
+ "microi-codex/SKILL.md": "364014d3e82eb4aa68d42e387f0cde913384256722262f5a31528a6269e865a0",
55
55
  "microi-datasource-mapping/SKILL.md": "44a125408e28241351f2dcdfa06932f2ba7e27b65f8b9b9b478ec13c31f208a1",
56
56
  "microi-db-schema/SKILL.md": "2ae10fc97599e2d0607b772d8e42934b712220062a003e320e3e34f1ad4a82e9",
57
57
  "microi-db-schema/agents/openai.yaml": "8454f13268c6bdbc272f81606401bc122c719abc919f906a2476f6f3f90f9826",
@@ -150,7 +150,7 @@
150
150
  "unity-integration/references/toolbox-migration.md": "b9294ea7db2b2a0f31e650e6e80f6d8f69385037bff6ac39fd5525ea98f8c934",
151
151
  "unity-integration/references/webgl-hosting.md": "5c19bda62d7c7a258b4fafc1d46e9a7c94e5400803d77d9aff44ce794083e745",
152
152
  "v8-api-config/SKILL.md": "572bb2918d7a80bd7dc3c6584ed2abd2e3fbd86ddffcbf4978abbddfec2d62ee",
153
- "v8-cache-pattern/SKILL.md": "39cd49f38c368cf88e0dbb1523d3e9d94798d01a22c923989f46b87b872b0cea",
153
+ "v8-cache-pattern/SKILL.md": "06f3e7a26f21a932f36fb5360f75603bbb0242287e381484890476346637177c",
154
154
  "v8-crud-api/SKILL.md": "17c187e0d6b8bba8f53111d4abcd64e12ab19b4b2a5d597c616d6599810ddc5c",
155
155
  "v8-crud-api/references/progressive-01-查询列表-分页.md": "482ac9efb5156871641724d0d9cc92aa9b0180cbe4d9092e9847d87a83e3232a",
156
156
  "v8-crud-api/references/progressive-02-where-条件语法速查.md": "234018d0d36427fb6af2df9fcf6b9c0e0d8a25f86cd1e89c577b17629f3451ab",
@@ -160,8 +160,8 @@
160
160
  "v8-export-import/references/progressive-01-excellayout-高级自由布局.md": "9444e53a1336478d0a8ec2f6f0ee7524a89315e410a27296c30807da5ca26296",
161
161
  "v8-export-import/references/progressive-02-powerpoint-导出.md": "21476a906316b07f3b4c21c723b3dd546d7393bcdbc80e715f0df9ab7e94cb9b",
162
162
  "v8-export-import/references/progressive-03-安全-性能注意.md": "006233ddd940b01b2cdd0deafa4e192fc3f2c74ffcc007fcecf88a50a11878a2",
163
- "v8-file-upload/SKILL.md": "c3191aaa9f4d5c78dc5cdb0573080ce089bd94530fe8cda5b081b1415fe77079",
164
- "v8-file-upload/references/progressive-01-公有桶-vs-私有桶.md": "69c3e8477667a3c3a4f59c59bd4d7e04c8f5d8e027179059ffeb052522ce9f72",
163
+ "v8-file-upload/SKILL.md": "fd0160e67d28fd34a3000a1aef704947cb96f8e1f6a4e928cc0b0ca4a2f3018e",
164
+ "v8-file-upload/references/progressive-01-公有桶-vs-私有桶.md": "fc8cba4c8bb5fbdc64d5fab2e8aeec307853872a3f8bc9cbf8a087b03c834289",
165
165
  "v8-file-upload/references/progressive-02-office-文件在线编辑版本号规则.md": "d51b34340a4f2cd64278da3c6949c1659e43ff5951171c4369465c95579e2791",
166
166
  "v8-formengine-http/SKILL.md": "4ecdfcc79a38477710538b88b897e0b1ebbefdd8664d3abcf8b91d7ad971edbc",
167
167
  "v8-frontend-events/SKILL.md": "fe8b5982e95b90e9e32b9332681fced932f209564537623598a008900b398f17",
@@ -183,7 +183,7 @@
183
183
  "v8-mq-mqtt/references/mqtt-production.md": "a31c73cb9f0af1705be6954f3ad8d00149ed1edf7f30d11b0915a261963b70b0",
184
184
  "v8-mq-mqtt/references/progressive-01-v8-mqtt-iot-物联网.md": "8d4b92753e0ff45a47c6f5e3d32b80b47808d7966faa41215743d6f479415551",
185
185
  "v8-mq-mqtt/scripts/check-mqtt-skill-coverage.mjs": "90a5e9cff201571eaec398fd2f058ac7425bb3ba518e3e5155ded409f4aaf041",
186
- "v8-saas-multi-tenant/SKILL.md": "9736a44bae5dad4df7f7a20243916ceceb5e012979c488a8b6373158eff533f5",
186
+ "v8-saas-multi-tenant/SKILL.md": "d533abad4b1adda2ae547c17f80f872761db6d2af5049f6c8d179c8911e2ac72",
187
187
  "v8-security/SKILL.md": "670bb824c6c268e5e1933df93ce41d78d6705eaa85f78e04a46670fc50ddcefa",
188
188
  "v8-security/references/progressive-01-2-权限校验.md": "d0401805aa8740d63606ee3725ae16ac6c07a16e71a546db89a8651d98244e16",
189
189
  "v8-security/references/progressive-02-7-日志记录.md": "02ea327f56c05bf0e442086f17d84a9f88fb40910ad8372e60f71c463100e46e",
@@ -210,196 +210,196 @@
210
210
  "workspace-conventions/references/progressive-03-cli-与-ide-插件错版共存约定.md": "eb021d1af0b4682ee9f6707666a92399f178f1c6ddca88e82ab49534820737ce"
211
211
  },
212
212
  "fileVersions": {
213
- ".microi-skills-version.json": "5.8.3",
214
- ".progressive-disclosure-manifest.json": "5.8.3",
215
- "README.md": "5.8.3",
216
- "ai-engine/SKILL.md": "5.8.3",
217
- "ai-engine/agents/openai.yaml": "5.8.3",
218
- "ai-engine/references/ai-employees.md": "5.8.3",
219
- "ai-engine/references/self-hosted-digital-human.md": "5.8.3",
220
- "ai-platform-governance/SKILL.md": "5.8.3",
221
- "ai-platform-governance/references/progressive-01-功能开关.md": "5.8.3",
222
- "app-store/SKILL.md": "5.8.3",
223
- "app-store/agents/openai.yaml": "5.8.3",
224
- "business-blueprint/SKILL.md": "5.8.3",
225
- "datasource-engine/SKILL.md": "5.8.3",
226
- "datasource-engine/agents/openai.yaml": "5.8.3",
227
- "dos-orm/SKILL.md": "5.8.3",
228
- "dos-orm/references/api-reference.md": "5.8.3",
229
- "email-engine/SKILL.md": "5.8.3",
230
- "email-engine/references/v8-email.md": "5.8.3",
231
- "job-engine/SKILL.md": "5.8.3",
232
- "job-engine/agents/openai.yaml": "5.8.3",
233
- "message-notification/SKILL.md": "5.8.3",
234
- "message-notification/agents/openai.yaml": "5.8.3",
235
- "message-notification/references/contracts.md": "5.8.3",
236
- "microi-ai-app-auth.js": "5.8.3",
237
- "microi-ai-application/SKILL.md": "5.8.3",
238
- "microi-ai-application/agents/openai.yaml": "5.8.3",
239
- "microi-ai-application/references/frontend-baseline.md": "5.8.3",
240
- "microi-client-frontend/SKILL.md": "5.8.3",
241
- "microi-client-frontend/references/progressive-01-3-动态按钮系统.md": "5.8.3",
242
- "microi-client-frontend/references/progressive-02-8-运行时高频坑复盘.md": "5.8.3",
243
- "microi-client-frontend/references/progressive-03-vue3-前端微服务宿主规则.md": "5.8.3",
244
- "microi-codex-installer/SKILL.md": "5.8.3",
245
- "microi-codex-installer/agents/openai.yaml": "5.8.3",
246
- "microi-codex/SKILL.md": "5.8.3",
247
- "microi-datasource-mapping/SKILL.md": "5.8.3",
248
- "microi-db-schema/SKILL.md": "5.8.3",
249
- "microi-db-schema/agents/openai.yaml": "5.8.3",
250
- "microi-db-schema/references/core-tables.md": "5.8.3",
251
- "microi-db-schema/references/form-component-options.md": "5.8.3",
252
- "microi-db-schema/references/schema-overview.md": "5.8.3",
253
- "microi-db-schema/references/schema.md": "5.8.3",
254
- "microi-db-schema/references/table-catalog.md": "5.8.3",
255
- "microi-deployment/SKILL.md": "5.8.3",
256
- "microi-deployment/references/deployment-matrix.md": "5.8.3",
257
- "microi-docs-coverage/SKILL.md": "5.8.3",
258
- "microi-docs-coverage/references/capability-map.md": "5.8.3",
259
- "microi-docs-coverage/scripts/audit-doc-skill-coverage.mjs": "5.8.3",
260
- "microi-form-engine/SKILL.md": "5.8.3",
261
- "microi-form-engine/references/component-catalog.md": "5.8.3",
262
- "microi-form-engine/references/data-source-events.md": "5.8.3",
263
- "microi-form-layout/SKILL.md": "5.8.3",
264
- "microi-form-layout/references/progressive-01-3-三种分组的存储与配置.md": "5.8.3",
265
- "microi-frontend-sdk/SKILL.md": "5.8.3",
266
- "microi-frontend-sdk/references/progressive-01-token-当前登录用户与当前终端登录协议.md": "5.8.3",
267
- "microi-left-right-layout/SKILL.md": "5.8.3",
268
- "microi-microservice/SKILL.md": "5.8.3",
269
- "microi-microservice/references/runtime-delivery.md": "5.8.3",
270
- "microi-mobile-app-quality/SKILL.md": "5.8.3",
271
- "microi-mobile-app-quality/references/progressive-01-4-重要按钮必须带图标.md": "5.8.3",
272
- "microi-mobile-app-quality/references/progressive-02-9-主题切换必须真实且全局生效.md": "5.8.3",
273
- "microi-solution-quotation/SKILL.md": "5.8.3",
274
- "microi-solution-quotation/agents/openai.yaml": "5.8.3",
275
- "microi-solution-quotation/scripts/build_solution_quote.py": "5.8.3",
276
- "microi-sso/SKILL.md": "5.8.3",
277
- "microi-sso/references/acceptance.md": "5.8.3",
278
- "microi-sso/references/configuration-and-security.md": "5.8.3",
279
- "microi-sso/references/inbound.md": "5.8.3",
280
- "microi-sso/references/outbound.md": "5.8.3",
281
- "microi-system-delivery/SKILL.md": "5.8.3",
282
- "microi-system-delivery/references/progressive-01-标准工作流.md": "5.8.3",
283
- "microi-system-delivery/references/progressive-02-自动化测试必须覆盖的坑.md": "5.8.3",
284
- "microi-ui/SKILL.md": "5.8.3",
285
- "microi-ui/references/progressive-01-移动端场景蓝图.md": "5.8.3",
286
- "microi-uniapp-frontend/SKILL.md": "5.8.3",
287
- "microi-uniapp-frontend/references/progressive-01-移动端分类-双栏列表独立滚动.md": "5.8.3",
288
- "microi-uniapp-frontend/references/progressive-02-关键业务资产不得默认选中.md": "5.8.3",
289
- "microi.v8.js": "5.8.3",
290
- "microi/SKILL.md": "5.8.3",
291
- "module-engine/SKILL.md": "5.8.3",
292
- "module-engine/references/module-config.md": "5.8.3",
293
- "ocr-engine/SKILL.md": "5.8.3",
294
- "ocr-engine/agents/openai.yaml": "5.8.3",
295
- "page-engine/SKILL.md": "5.8.3",
296
- "page-engine/examples/compact-dashboard.json": "5.8.3",
297
- "page-engine/references/progressive-01-所有组件类型.md": "5.8.3",
298
- "page-engine/references/progressive-02-版本历史-并发保存与回滚.md": "5.8.3",
299
- "performance-testing/SKILL.md": "5.8.3",
300
- "playwright-e2e/SKILL.md": "5.8.3",
301
- "playwright-e2e/references/progressive-01-全自动登录-免验证码-但不免密码-必读.md": "5.8.3",
302
- "playwright-e2e/references/progressive-02-文字对比度与可读性自动化检查-必做.md": "5.8.3",
303
- "playwright-e2e/references/progressive-03-microi-helper-模板.md": "5.8.3",
304
- "playwright-e2e/references/progressive-04-ci-建议.md": "5.8.3",
305
- "print-engine/SKILL.md": "5.8.3",
306
- "production-readonly-audit/SKILL.md": "5.8.3",
307
- "report-engine/SKILL.md": "5.8.3",
308
- "report-engine/agents/openai.yaml": "5.8.3",
309
- "scripts/optimize-progressive-disclosure.mjs": "5.8.3",
310
- "scripts/refresh-progressive-disclosure.mjs": "5.8.3",
311
- "scripts/sync-embedded-skills.mjs": "5.8.3",
312
- "scripts/validate-progressive-disclosure.mjs": "5.8.3",
313
- "search-engine/SKILL.md": "5.8.3",
314
- "search-engine/agents/openai.yaml": "5.8.3",
315
- "spider-engine/SKILL.md": "5.8.3",
316
- "system-observability/SKILL.md": "5.8.3",
317
- "system-observability/references/memory-incident-triage.md": "5.8.3",
318
- "translate-engine/SKILL.md": "5.8.3",
319
- "translate-engine/agents/openai.yaml": "5.8.3",
320
- "ui-design/SKILL.md": "5.8.3",
321
- "ui-design/assets/pattern-showcase/app.js": "5.8.3",
322
- "ui-design/assets/pattern-showcase/index.html": "5.8.3",
323
- "ui-design/assets/pattern-showcase/styles.css": "5.8.3",
324
- "ui-design/assets/templates/MCI-DESIGN.md": "5.8.3",
325
- "ui-design/references/design-pattern-library.md": "5.8.3",
326
- "ui-design/references/mci-design-contract.md": "5.8.3",
327
- "ui-design/references/motion-and-media.md": "5.8.3",
328
- "ui-design/references/product-flow-recipes.md": "5.8.3",
329
- "ui-design/references/progressive-01-颜色体系-css-variables-支持主题切换.md": "5.8.3",
330
- "ui-design/references/progressive-02-字体.md": "5.8.3",
331
- "ui-design/references/progressive-03-动效规范-丰富但不卡.md": "5.8.3",
332
- "ui-design/references/progressive-04-组件风格速查.md": "5.8.3",
333
- "ui-design/references/progressive-05-移动端专用规范.md": "5.8.3",
334
- "ui-design/references/progressive-06-主题切换实现.md": "5.8.3",
335
- "ui-design/references/progressive-07-速查-从头搭建一个移动端页面.md": "5.8.3",
336
- "ui-design/references/progressive-08-表单分组规范-tabs-vs-collapsegroup-强制.md": "5.8.3",
337
- "uniapp-mall-assets/SKILL.md": "5.8.3",
338
- "unity-integration/SKILL.md": "5.8.3",
339
- "unity-integration/agents/openai.yaml": "5.8.3",
340
- "unity-integration/references/ai-app-delivery.md": "5.8.3",
341
- "unity-integration/references/sdk-api.md": "5.8.3",
342
- "unity-integration/references/toolbox-migration.md": "5.8.3",
343
- "unity-integration/references/webgl-hosting.md": "5.8.3",
344
- "v8-api-config/SKILL.md": "5.8.3",
345
- "v8-cache-pattern/SKILL.md": "5.8.3",
346
- "v8-crud-api/SKILL.md": "5.8.3",
347
- "v8-crud-api/references/progressive-01-查询列表-分页.md": "5.8.3",
348
- "v8-crud-api/references/progressive-02-where-条件语法速查.md": "5.8.3",
349
- "v8-debugging/SKILL.md": "5.8.3",
350
- "v8-explorer-tree/SKILL.md": "5.8.3",
351
- "v8-export-import/SKILL.md": "5.8.3",
352
- "v8-export-import/references/progressive-01-excellayout-高级自由布局.md": "5.8.3",
353
- "v8-export-import/references/progressive-02-powerpoint-导出.md": "5.8.3",
354
- "v8-export-import/references/progressive-03-安全-性能注意.md": "5.8.3",
355
- "v8-file-upload/SKILL.md": "5.8.3",
356
- "v8-file-upload/references/progressive-01-公有桶-vs-私有桶.md": "5.8.3",
357
- "v8-file-upload/references/progressive-02-office-文件在线编辑版本号规则.md": "5.8.3",
358
- "v8-formengine-http/SKILL.md": "5.8.3",
359
- "v8-frontend-events/SKILL.md": "5.8.3",
360
- "v8-frontend-events/references/bluetooth-print-api.md": "5.8.3",
361
- "v8-frontend-events/references/bluetooth-print.md": "5.8.3",
362
- "v8-frontend-events/references/progressive-01-列表事件.md": "5.8.3",
363
- "v8-http-integration/SKILL.md": "5.8.3",
364
- "v8-http-integration/references/progressive-01-get-请求.md": "5.8.3",
365
- "v8-http-integration/references/progressive-02-错误处理模式.md": "5.8.3",
366
- "v8-image-processing/SKILL.md": "5.8.3",
367
- "v8-image-processing/agents/openai.yaml": "5.8.3",
368
- "v8-image-processing/references/api-reference.md": "5.8.3",
369
- "v8-menu-buttons/SKILL.md": "5.8.3",
370
- "v8-menu-buttons/references/progressive-01-2-按钮对象-schema.md": "5.8.3",
371
- "v8-menu-buttons/references/progressive-02-8-模式-f-后台任务按钮-长任务.md": "5.8.3",
372
- "v8-menu-buttons/references/progressive-03-10-反模式-避免.md": "5.8.3",
373
- "v8-mongodb/SKILL.md": "5.8.3",
374
- "v8-mq-mqtt/SKILL.md": "5.8.3",
375
- "v8-mq-mqtt/references/mqtt-production.md": "5.8.3",
376
- "v8-mq-mqtt/references/progressive-01-v8-mqtt-iot-物联网.md": "5.8.3",
377
- "v8-mq-mqtt/scripts/check-mqtt-skill-coverage.mjs": "5.8.3",
378
- "v8-saas-multi-tenant/SKILL.md": "5.8.3",
379
- "v8-security/SKILL.md": "5.8.3",
380
- "v8-security/references/progressive-01-2-权限校验.md": "5.8.3",
381
- "v8-security/references/progressive-02-7-日志记录.md": "5.8.3",
382
- "v8-sql-query/SKILL.md": "5.8.3",
383
- "v8-table-event/SKILL.md": "5.8.3",
384
- "v8-table-event/references/progressive-01-informv8-js-表单打开事件.md": "5.8.3",
385
- "v8-table-event/references/progressive-02-前端事件名-v8-eventname-可能的值.md": "5.8.3",
386
- "v8-tcp-integration/SKILL.md": "5.8.3",
387
- "v8-tcp-integration/agents/openai.yaml": "5.8.3",
388
- "v8-template-engine/SKILL.md": "5.8.3",
389
- "v8-utilities/SKILL.md": "5.8.3",
390
- "v8-utilities/references/client-api-index.md": "5.8.3",
391
- "v8-utilities/references/platform-http-routes.md": "5.8.3",
392
- "v8-utilities/references/server-api-index.md": "5.8.3",
393
- "v8-workflow/SKILL.md": "5.8.3",
394
- "v8-workflow/references/progressive-01-节点开始-v8-事件.md": "5.8.3",
395
- "v8-workflow/references/workflow-configuration.md": "5.8.3",
396
- "vision-engine/SKILL.md": "5.8.3",
397
- "vision-engine/agents/openai.yaml": "5.8.3",
398
- "vision-engine/references/architecture-and-acceptance.md": "5.8.3",
399
- "workspace-conventions/SKILL.md": "5.8.3",
400
- "workspace-conventions/references/progressive-01-版本更新日志保护规则-强制.md": "5.8.3",
401
- "workspace-conventions/references/progressive-02-microi-net-api-本地启动约定.md": "5.8.3",
402
- "workspace-conventions/references/progressive-03-cli-与-ide-插件错版共存约定.md": "5.8.3"
213
+ ".microi-skills-version.json": "5.8.4",
214
+ ".progressive-disclosure-manifest.json": "5.8.4",
215
+ "README.md": "5.8.4",
216
+ "ai-engine/SKILL.md": "5.8.4",
217
+ "ai-engine/agents/openai.yaml": "5.8.4",
218
+ "ai-engine/references/ai-employees.md": "5.8.4",
219
+ "ai-engine/references/self-hosted-digital-human.md": "5.8.4",
220
+ "ai-platform-governance/SKILL.md": "5.8.4",
221
+ "ai-platform-governance/references/progressive-01-功能开关.md": "5.8.4",
222
+ "app-store/SKILL.md": "5.8.4",
223
+ "app-store/agents/openai.yaml": "5.8.4",
224
+ "business-blueprint/SKILL.md": "5.8.4",
225
+ "datasource-engine/SKILL.md": "5.8.4",
226
+ "datasource-engine/agents/openai.yaml": "5.8.4",
227
+ "dos-orm/SKILL.md": "5.8.4",
228
+ "dos-orm/references/api-reference.md": "5.8.4",
229
+ "email-engine/SKILL.md": "5.8.4",
230
+ "email-engine/references/v8-email.md": "5.8.4",
231
+ "job-engine/SKILL.md": "5.8.4",
232
+ "job-engine/agents/openai.yaml": "5.8.4",
233
+ "message-notification/SKILL.md": "5.8.4",
234
+ "message-notification/agents/openai.yaml": "5.8.4",
235
+ "message-notification/references/contracts.md": "5.8.4",
236
+ "microi-ai-app-auth.js": "5.8.4",
237
+ "microi-ai-application/SKILL.md": "5.8.4",
238
+ "microi-ai-application/agents/openai.yaml": "5.8.4",
239
+ "microi-ai-application/references/frontend-baseline.md": "5.8.4",
240
+ "microi-client-frontend/SKILL.md": "5.8.4",
241
+ "microi-client-frontend/references/progressive-01-3-动态按钮系统.md": "5.8.4",
242
+ "microi-client-frontend/references/progressive-02-8-运行时高频坑复盘.md": "5.8.4",
243
+ "microi-client-frontend/references/progressive-03-vue3-前端微服务宿主规则.md": "5.8.4",
244
+ "microi-codex-installer/SKILL.md": "5.8.4",
245
+ "microi-codex-installer/agents/openai.yaml": "5.8.4",
246
+ "microi-codex/SKILL.md": "5.8.4",
247
+ "microi-datasource-mapping/SKILL.md": "5.8.4",
248
+ "microi-db-schema/SKILL.md": "5.8.4",
249
+ "microi-db-schema/agents/openai.yaml": "5.8.4",
250
+ "microi-db-schema/references/core-tables.md": "5.8.4",
251
+ "microi-db-schema/references/form-component-options.md": "5.8.4",
252
+ "microi-db-schema/references/schema-overview.md": "5.8.4",
253
+ "microi-db-schema/references/schema.md": "5.8.4",
254
+ "microi-db-schema/references/table-catalog.md": "5.8.4",
255
+ "microi-deployment/SKILL.md": "5.8.4",
256
+ "microi-deployment/references/deployment-matrix.md": "5.8.4",
257
+ "microi-docs-coverage/SKILL.md": "5.8.4",
258
+ "microi-docs-coverage/references/capability-map.md": "5.8.4",
259
+ "microi-docs-coverage/scripts/audit-doc-skill-coverage.mjs": "5.8.4",
260
+ "microi-form-engine/SKILL.md": "5.8.4",
261
+ "microi-form-engine/references/component-catalog.md": "5.8.4",
262
+ "microi-form-engine/references/data-source-events.md": "5.8.4",
263
+ "microi-form-layout/SKILL.md": "5.8.4",
264
+ "microi-form-layout/references/progressive-01-3-三种分组的存储与配置.md": "5.8.4",
265
+ "microi-frontend-sdk/SKILL.md": "5.8.4",
266
+ "microi-frontend-sdk/references/progressive-01-token-当前登录用户与当前终端登录协议.md": "5.8.4",
267
+ "microi-left-right-layout/SKILL.md": "5.8.4",
268
+ "microi-microservice/SKILL.md": "5.8.4",
269
+ "microi-microservice/references/runtime-delivery.md": "5.8.4",
270
+ "microi-mobile-app-quality/SKILL.md": "5.8.4",
271
+ "microi-mobile-app-quality/references/progressive-01-4-重要按钮必须带图标.md": "5.8.4",
272
+ "microi-mobile-app-quality/references/progressive-02-9-主题切换必须真实且全局生效.md": "5.8.4",
273
+ "microi-solution-quotation/SKILL.md": "5.8.4",
274
+ "microi-solution-quotation/agents/openai.yaml": "5.8.4",
275
+ "microi-solution-quotation/scripts/build_solution_quote.py": "5.8.4",
276
+ "microi-sso/SKILL.md": "5.8.4",
277
+ "microi-sso/references/acceptance.md": "5.8.4",
278
+ "microi-sso/references/configuration-and-security.md": "5.8.4",
279
+ "microi-sso/references/inbound.md": "5.8.4",
280
+ "microi-sso/references/outbound.md": "5.8.4",
281
+ "microi-system-delivery/SKILL.md": "5.8.4",
282
+ "microi-system-delivery/references/progressive-01-标准工作流.md": "5.8.4",
283
+ "microi-system-delivery/references/progressive-02-自动化测试必须覆盖的坑.md": "5.8.4",
284
+ "microi-ui/SKILL.md": "5.8.4",
285
+ "microi-ui/references/progressive-01-移动端场景蓝图.md": "5.8.4",
286
+ "microi-uniapp-frontend/SKILL.md": "5.8.4",
287
+ "microi-uniapp-frontend/references/progressive-01-移动端分类-双栏列表独立滚动.md": "5.8.4",
288
+ "microi-uniapp-frontend/references/progressive-02-关键业务资产不得默认选中.md": "5.8.4",
289
+ "microi.v8.js": "5.8.4",
290
+ "microi/SKILL.md": "5.8.4",
291
+ "module-engine/SKILL.md": "5.8.4",
292
+ "module-engine/references/module-config.md": "5.8.4",
293
+ "ocr-engine/SKILL.md": "5.8.4",
294
+ "ocr-engine/agents/openai.yaml": "5.8.4",
295
+ "page-engine/SKILL.md": "5.8.4",
296
+ "page-engine/examples/compact-dashboard.json": "5.8.4",
297
+ "page-engine/references/progressive-01-所有组件类型.md": "5.8.4",
298
+ "page-engine/references/progressive-02-版本历史-并发保存与回滚.md": "5.8.4",
299
+ "performance-testing/SKILL.md": "5.8.4",
300
+ "playwright-e2e/SKILL.md": "5.8.4",
301
+ "playwright-e2e/references/progressive-01-全自动登录-免验证码-但不免密码-必读.md": "5.8.4",
302
+ "playwright-e2e/references/progressive-02-文字对比度与可读性自动化检查-必做.md": "5.8.4",
303
+ "playwright-e2e/references/progressive-03-microi-helper-模板.md": "5.8.4",
304
+ "playwright-e2e/references/progressive-04-ci-建议.md": "5.8.4",
305
+ "print-engine/SKILL.md": "5.8.4",
306
+ "production-readonly-audit/SKILL.md": "5.8.4",
307
+ "report-engine/SKILL.md": "5.8.4",
308
+ "report-engine/agents/openai.yaml": "5.8.4",
309
+ "scripts/optimize-progressive-disclosure.mjs": "5.8.4",
310
+ "scripts/refresh-progressive-disclosure.mjs": "5.8.4",
311
+ "scripts/sync-embedded-skills.mjs": "5.8.4",
312
+ "scripts/validate-progressive-disclosure.mjs": "5.8.4",
313
+ "search-engine/SKILL.md": "5.8.4",
314
+ "search-engine/agents/openai.yaml": "5.8.4",
315
+ "spider-engine/SKILL.md": "5.8.4",
316
+ "system-observability/SKILL.md": "5.8.4",
317
+ "system-observability/references/memory-incident-triage.md": "5.8.4",
318
+ "translate-engine/SKILL.md": "5.8.4",
319
+ "translate-engine/agents/openai.yaml": "5.8.4",
320
+ "ui-design/SKILL.md": "5.8.4",
321
+ "ui-design/assets/pattern-showcase/app.js": "5.8.4",
322
+ "ui-design/assets/pattern-showcase/index.html": "5.8.4",
323
+ "ui-design/assets/pattern-showcase/styles.css": "5.8.4",
324
+ "ui-design/assets/templates/MCI-DESIGN.md": "5.8.4",
325
+ "ui-design/references/design-pattern-library.md": "5.8.4",
326
+ "ui-design/references/mci-design-contract.md": "5.8.4",
327
+ "ui-design/references/motion-and-media.md": "5.8.4",
328
+ "ui-design/references/product-flow-recipes.md": "5.8.4",
329
+ "ui-design/references/progressive-01-颜色体系-css-variables-支持主题切换.md": "5.8.4",
330
+ "ui-design/references/progressive-02-字体.md": "5.8.4",
331
+ "ui-design/references/progressive-03-动效规范-丰富但不卡.md": "5.8.4",
332
+ "ui-design/references/progressive-04-组件风格速查.md": "5.8.4",
333
+ "ui-design/references/progressive-05-移动端专用规范.md": "5.8.4",
334
+ "ui-design/references/progressive-06-主题切换实现.md": "5.8.4",
335
+ "ui-design/references/progressive-07-速查-从头搭建一个移动端页面.md": "5.8.4",
336
+ "ui-design/references/progressive-08-表单分组规范-tabs-vs-collapsegroup-强制.md": "5.8.4",
337
+ "uniapp-mall-assets/SKILL.md": "5.8.4",
338
+ "unity-integration/SKILL.md": "5.8.4",
339
+ "unity-integration/agents/openai.yaml": "5.8.4",
340
+ "unity-integration/references/ai-app-delivery.md": "5.8.4",
341
+ "unity-integration/references/sdk-api.md": "5.8.4",
342
+ "unity-integration/references/toolbox-migration.md": "5.8.4",
343
+ "unity-integration/references/webgl-hosting.md": "5.8.4",
344
+ "v8-api-config/SKILL.md": "5.8.4",
345
+ "v8-cache-pattern/SKILL.md": "5.8.4",
346
+ "v8-crud-api/SKILL.md": "5.8.4",
347
+ "v8-crud-api/references/progressive-01-查询列表-分页.md": "5.8.4",
348
+ "v8-crud-api/references/progressive-02-where-条件语法速查.md": "5.8.4",
349
+ "v8-debugging/SKILL.md": "5.8.4",
350
+ "v8-explorer-tree/SKILL.md": "5.8.4",
351
+ "v8-export-import/SKILL.md": "5.8.4",
352
+ "v8-export-import/references/progressive-01-excellayout-高级自由布局.md": "5.8.4",
353
+ "v8-export-import/references/progressive-02-powerpoint-导出.md": "5.8.4",
354
+ "v8-export-import/references/progressive-03-安全-性能注意.md": "5.8.4",
355
+ "v8-file-upload/SKILL.md": "5.8.4",
356
+ "v8-file-upload/references/progressive-01-公有桶-vs-私有桶.md": "5.8.4",
357
+ "v8-file-upload/references/progressive-02-office-文件在线编辑版本号规则.md": "5.8.4",
358
+ "v8-formengine-http/SKILL.md": "5.8.4",
359
+ "v8-frontend-events/SKILL.md": "5.8.4",
360
+ "v8-frontend-events/references/bluetooth-print-api.md": "5.8.4",
361
+ "v8-frontend-events/references/bluetooth-print.md": "5.8.4",
362
+ "v8-frontend-events/references/progressive-01-列表事件.md": "5.8.4",
363
+ "v8-http-integration/SKILL.md": "5.8.4",
364
+ "v8-http-integration/references/progressive-01-get-请求.md": "5.8.4",
365
+ "v8-http-integration/references/progressive-02-错误处理模式.md": "5.8.4",
366
+ "v8-image-processing/SKILL.md": "5.8.4",
367
+ "v8-image-processing/agents/openai.yaml": "5.8.4",
368
+ "v8-image-processing/references/api-reference.md": "5.8.4",
369
+ "v8-menu-buttons/SKILL.md": "5.8.4",
370
+ "v8-menu-buttons/references/progressive-01-2-按钮对象-schema.md": "5.8.4",
371
+ "v8-menu-buttons/references/progressive-02-8-模式-f-后台任务按钮-长任务.md": "5.8.4",
372
+ "v8-menu-buttons/references/progressive-03-10-反模式-避免.md": "5.8.4",
373
+ "v8-mongodb/SKILL.md": "5.8.4",
374
+ "v8-mq-mqtt/SKILL.md": "5.8.4",
375
+ "v8-mq-mqtt/references/mqtt-production.md": "5.8.4",
376
+ "v8-mq-mqtt/references/progressive-01-v8-mqtt-iot-物联网.md": "5.8.4",
377
+ "v8-mq-mqtt/scripts/check-mqtt-skill-coverage.mjs": "5.8.4",
378
+ "v8-saas-multi-tenant/SKILL.md": "5.8.4",
379
+ "v8-security/SKILL.md": "5.8.4",
380
+ "v8-security/references/progressive-01-2-权限校验.md": "5.8.4",
381
+ "v8-security/references/progressive-02-7-日志记录.md": "5.8.4",
382
+ "v8-sql-query/SKILL.md": "5.8.4",
383
+ "v8-table-event/SKILL.md": "5.8.4",
384
+ "v8-table-event/references/progressive-01-informv8-js-表单打开事件.md": "5.8.4",
385
+ "v8-table-event/references/progressive-02-前端事件名-v8-eventname-可能的值.md": "5.8.4",
386
+ "v8-tcp-integration/SKILL.md": "5.8.4",
387
+ "v8-tcp-integration/agents/openai.yaml": "5.8.4",
388
+ "v8-template-engine/SKILL.md": "5.8.4",
389
+ "v8-utilities/SKILL.md": "5.8.4",
390
+ "v8-utilities/references/client-api-index.md": "5.8.4",
391
+ "v8-utilities/references/platform-http-routes.md": "5.8.4",
392
+ "v8-utilities/references/server-api-index.md": "5.8.4",
393
+ "v8-workflow/SKILL.md": "5.8.4",
394
+ "v8-workflow/references/progressive-01-节点开始-v8-事件.md": "5.8.4",
395
+ "v8-workflow/references/workflow-configuration.md": "5.8.4",
396
+ "vision-engine/SKILL.md": "5.8.4",
397
+ "vision-engine/agents/openai.yaml": "5.8.4",
398
+ "vision-engine/references/architecture-and-acceptance.md": "5.8.4",
399
+ "workspace-conventions/SKILL.md": "5.8.4",
400
+ "workspace-conventions/references/progressive-01-版本更新日志保护规则-强制.md": "5.8.4",
401
+ "workspace-conventions/references/progressive-02-microi-net-api-本地启动约定.md": "5.8.4",
402
+ "workspace-conventions/references/progressive-03-cli-与-ide-插件错版共存约定.md": "5.8.4"
403
403
  },
404
404
  "files": [
405
405
  ".microi-skills-version.json",
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "5.8.3",
2
+ "version": "5.8.4",
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.Agent/bump-version.js",
5
- "updatedAt": "2026-10-06T22:27:09.603Z"
5
+ "updatedAt": "2026-10-08T11:43:08.967Z"
6
6
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 1,
3
- "generatedAt": "2026-10-07T02:28:38.552Z",
3
+ "generatedAt": "2026-10-07T14:09:52.345Z",
4
4
  "policy": {
5
5
  "maxEntryLines": 285,
6
6
  "referenceBudgetLines": 245,
@@ -2221,8 +2221,8 @@
2221
2221
  ]
2222
2222
  },
2223
2223
  "v8-file-upload": {
2224
- "originalSha256": "5b8d223cd64bf4dcd358b9d877776f8bb3b6df23e2545990455f037d4fbd185e",
2225
- "originalLines": 667,
2224
+ "originalSha256": "9bdc4b16083244c769999a003d6e3cfe3ed77e8d5d730c53dd8f58168cc26337",
2225
+ "originalLines": 673,
2226
2226
  "prefixSha256": "01a5357a6c11c20c56f70178e843dd0d2aac92e796042c0bc582e72c967f1ad1",
2227
2227
  "prefixBytes": 16221,
2228
2228
  "entryLines": 285,
@@ -2231,7 +2231,7 @@
2231
2231
  "id": "v8-file-upload-000",
2232
2232
  "ordinal": 0,
2233
2233
  "destination": "v8-file-upload/SKILL.md",
2234
- "sha256": "d134ef9d7df6a00a6f11149a7f73595d96d4feb0ffa159e520136c72de7f495a",
2234
+ "sha256": "9402f7173710e8d110392f184119154a50187138ab7d698fce0b73b5f12123e2",
2235
2235
  "lines": 20,
2236
2236
  "heading": "核心 API"
2237
2237
  },
@@ -2271,8 +2271,8 @@
2271
2271
  "id": "v8-file-upload-005",
2272
2272
  "ordinal": 3,
2273
2273
  "destination": "v8-file-upload/references/progressive-01-公有桶-vs-私有桶.md",
2274
- "sha256": "0b4d57f32bfe913c3a2567d2e2a86f4d5ba505d60c4348ad472c117774bbfc31",
2275
- "lines": 173,
2274
+ "sha256": "71cebd2f6946be49188c430c146b9ee923ceb0719fbda4bd3701b40152732cae",
2275
+ "lines": 179,
2276
2276
  "heading": "公有桶 vs 私有桶"
2277
2277
  },
2278
2278
  {
@@ -142,10 +142,17 @@ Inspect 和 Publish 使用完全相同的选择、`CommittedProof` 及运行清
142
142
  使用既有 `CopyObject/ObjectExist/GetObjectSha256` 校验复制目标的原始字节与长度后再更新
143
143
  当前元数据。同版本重装也修正旧路径;复制响应未知先回读目标,目标不同或能力缺失失败
144
144
  关闭。复制及当前游标的对象验签计入分片预算,持久前缀只复用同一包摘要根的精确元数据。
145
+ 安装器从 `Build/BuildRepair` 或后续应用检查点恢复时,已完成的源码前缀仍按同一
146
+ 清单摘要根复用,不能重新消耗源码分片预算并退回 `Source`。未知资产类型、当前及
147
+ 后续未校验条目、非规范根或元数据差异仍需验证;升级导入器后恢复原任务及原请求键。
145
148
  ZIP 导出前后必须以原始 `FilePath/ContentHash/Size` 的完整当前清单重新核对 `store-` 根
146
149
  摘要;分片切换后的部分旧根、清单漂移和摘要根格式错误均拒绝。去掉 `source/` 的归档名
147
150
  不能代替安装根摘要的原始路径。
148
151
  安装成功后仍须下载并核验原生源码 ZIP,不能削弱其权限、租户、路径或字节校验。
152
+ 大型 UTF8 源码应复用既有 `GetPrivateFileText/Sha256Hex/StringToBase64` 字符串边界,
153
+ 在原字节摘要一致后才采用,避免 CLR byte[] 逐字节复制到 Jint。二进制或有损解码继续
154
+ 保留原字节路径;文本读取失败或异常不能退回另一条存储路径。Base64 长度与最终 ZIP
155
+ 实际条目仍严格验证,旧宿主缺少文本/编码能力时才直接沿用原兼容路径。
149
156
  缺失基线不回退历史;分页不完整、重复路径(含大小写)、对象后缀与归档路径不一致、
150
157
  大小或原始字节 SHA 漂移均停止。使用当前租户可信私有字节与已有 ZIP 原子,优先对同一
151
158
  返回归档调用可信 `ExtractZip`(兼容 `ReadZip`),完整核对每条路径、大小、原始字节 SHA、
@@ -511,6 +518,7 @@ staged 行、请求参数、`StableFilePathName` 或外部 CDN URL 推断版本
511
518
  - 根因:把平台运行依赖维护成手写短清单,并只复制 SaaS 单包;接口之间的 `V8.ApiEngine.Run` 依赖、其它官方平台应用和个性化 Hook 没有进入同一闭包,旧数据库也没有可靠的启动前自愈与逐项回读。
512
519
  - 强制规则:启动前接口闭包必须由全部内置官方平台应用包动态计算,并递归解析接口调用;当前官方基线为 9 个包、106 个接口(98 个 `Managed`、8 个 `CreateIfMissing`),数量只是发布快照,运行逻辑不得硬编码。门禁逐项校验 Key、地址、启用状态、匿名/HTTP 状态和源码策略;缺失时从受信内置包按原所有权补齐,所有项严格回读成功后才对外提供流量。`CreateIfMissing` 首次创建后永不覆盖客户代码。
513
520
  - 控制面自举:官方资源发布必须先保证 `get-microi-upgrade-resource` 自身达到当前协议,再发布其它包;若控制面旧版本不能校验新包,先只发布并回读这一项,刷新动态路由缓存后再发布剩余资源。发布响应超时或 Redis 广播失败时先按资源 SHA 回读判断提交/回滚,禁止盲目重放。
521
+ - 包内明确声明 `Managed` 的 `get-microi-upgrade-resource` 必须和其他受管接口一同原位覆盖;禁止硬编码跳过该 Key 却记安装成功。无 Managed 声明的历史包保留保护边界,官方发布/投影仍需可信后端鉴权。验收核对完整源码、版本、稳定 Id 和路由,不只读取安装状态。
514
522
  - 独立系统日志包的接口投影使用 `ReconcilePublishedApiEngines` 与显式 `ProjectionScope: 'SystemLog'`,仅允许单一 `app.microi.sys-log.json`,且包内 `PackageInfo.AppId` 必须为 `app.microi.sys-log`、`ExpectedSha256` 必须等于已发布完整包摘要。默认九包全量规则保持不变;未知范围、其它文件或部分九包选择都应拒绝。仍须执行官方鉴权、事务行锁、Managed/CreateIfMissing 规则及完整回读,不能将母版投影当作客户已安装。
515
523
  - 兼容与验收:历史 Controller 回退不能再转调可能缺失的同一个接口引擎;保留旧路由时必须使用可信 Core 原子或明确返回可诊断兼容结果。自动化测试应扫描 PC、UniApp、内置应用包和接口源码的全部 `/apiengine/` 与 `V8.ApiEngine.Run` 引用,证明每个依赖由官方包声明;真实启动必须对每个启用租户输出开始、缺项、修复、逐项成功及最终汇总日志,并同时验证匿名、登录态、商城批量计划和重复启动幂等。
516
524
 
@@ -7,6 +7,12 @@ description: 在 Microi Agent、Codex 或 DeepSeek Harness 中完成 Microi吾
7
7
 
8
8
  本插件与 `Microi.Agent`、`@microi.net/cli` 共用配置、Token、MCP Server 和 Microi Skills。不要另写原生 HTTP、SQL 或第二套认证实现。
9
9
 
10
+ 本地 HTTPS 连接同样必须验证证书。MCP 不因 `localhost/127.0.0.1` 自动设置
11
+ `NODE_TLS_REJECT_UNAUTHORIZED=0`,也不能覆盖调用方的严格策略。开发节点使用受信
12
+ 证书;必要时在启动 MCP 前通过 `NODE_EXTRA_CA_CERTS` 指定已核验的公开 CA PEM。
13
+ 分别验证正确 CA 可连接、陌生 CA/无信任证书被拒绝;配置了 CA 不等于实际启用了
14
+ 证书验证,须核对最终进程与真实握手结果。证书私钥和会话 Token 不进入日志。
15
+
10
16
  平台 Api/Web 版本入口可生成独立开发工具连接。收到连接 JSON 时,用 `microi auth import --session-stdin` 从标准输入导入,再运行 `microi ai init` 和 `microi doctor`;禁止将 Token 放入命令行、源码或日志,不再索取账号密码。开发 Token 使用现有终端有效期,可独立撤销;它只授权该业务租户,不能替代 Microi Agent 的官方 AI 计费账号登录。访问密钥的最小业务 scope 不能替代完整 MCP 管理身份。第三方 App Secret 默认进入系统设置“安全与服务接入”,优先使用 `microi_manage_server_private_secret`。
11
17
 
12
18
  每次 Microi 对话先完整读取工作区 `microi.skills/workspace-conventions/SKILL.md`;工作区尚未初始化时读取本插件同级 `../workspace-conventions/SKILL.md`。按其中首部完成创始人身份识别及平台功能四项同步检查,再进入专项流程;完整规则只维护该基础入口,不复制到本路由。
@@ -119,6 +119,12 @@ var foreignKey = 'Microi:other-tenant:User:' + userId;
119
119
  - L1:进程内静态 `ConcurrentDictionary<string, CacheEntry>`(每个 API 进程独立)
120
120
  - L2:当前租户的 Redis(同一租户各 API 节点共享)
121
121
 
122
+ 平台 L1 容量淘汰先调用 `ConcurrentDictionary.ToArray()` 取得一致快照,再按过期时间
123
+ 排序;禁止直接让 LINQ 对并发字典执行依赖 `Count/CopyTo` 的物化。淘汰与过期清理
124
+ 只移除仍是快照旧值的条目,保留扫描后被刷新的新值。登录或接口路由读取在缓存淘汰
125
+ 栈出现空引用/数组容量异常时,先核对实际 API 二进制与该内核修复;不要修改业务 V8、
126
+ 清空 Redis 或关闭缓存掩盖问题。源码回归、API 加载及线上复测分别记录。
127
+
122
128
  缓存组件读取顺序:L1 命中 → L2 命中并回填 L1 → 返回未命中。它本身不查询
123
129
  业务数据库;数据库查询与回填属于调用方的 Cache-Aside 流程。
124
130
 
@@ -89,7 +89,7 @@ description: Microi V8 与 MCP 文件上传下载指南。用于处理流式 AI
89
89
  官网客户端读取私有文件统一调用 `/apiengine/platform-private-file-url`,提交 `FilePathName` 或有界 `FilePathNames`,并按资源类型提供权威定位参数:普通表单字段使用 `FormEngineKey + FormDataId + FieldId + SysMenuId`;用户头像使用 `ResourceKind=UserAvatar + ResourceId=用户Id`;菜单/部门导入模板分别使用 `MenuImportTemplate`、`DeptImportTemplate` 与对应记录 Id。CAD 私有派生预览使用 `ResourceKind=FormFieldDerivedPreview`,除表单四元组外必须同时提交字段中保存的 `OriginalFilePathName` 和单个派生 `FilePathName`;后端只接受同目录同 basename 的 DWG→`_preview.dxf`、STEP/STP→`_preview.stl` 唯一映射,并在对象存在后签名。文件柜对象使用 `ResourceKind=FileManagerObject`,`ResourceId` 必须与单个 `FilePathName` 大小写精确相同,并提交能力探针返回的当前租户权威 `SysMenuId`;此类签名只允许平台超级管理员 DiyToken 会话,访问密钥和普通菜单用户一律拒绝。后端会从权威字段或对象存储重新读取并精确匹配路径;管理员也不能只传裸路径绕过对象引用,普通客户端禁止换取私有文件原始 Byte/Stream。旧 `/api/HDFS/GetPrivateFileUrl` 与 `/api/HDFS/MallFileUrl` 只保留令牌格式兼容并转发同一 Managed 接口,新代码不得继续引用。
90
90
 
91
91
  <!-- microi-progressive:begin -->
92
- <!-- microi-progressive:chunk id=v8-file-upload-000 sha256=d134ef9d7df6a00a6f11149a7f73595d96d4feb0ffa159e520136c72de7f495a -->
92
+ <!-- microi-progressive:chunk id=v8-file-upload-000 sha256=9402f7173710e8d110392f184119154a50187138ab7d698fce0b73b5f12123e2 -->
93
93
  ## 核心 API
94
94
 
95
95
  | API | 说明 |
@@ -105,7 +105,7 @@ description: Microi V8 与 MCP 文件上传下载指南。用于处理流式 AI
105
105
  | `V8.Http.GetResponse({Url}).RawBytes` | 下载远程文件为字节数组 |
106
106
  | 接口返回 `{ FileName, ContentType, FileByteBase64 }` | 接口直接响应文件 |
107
107
 
108
- 固定 CDN 应用回填优先使用服务端 `CopyObject`,公有桶复制编译资产、私有桶复制源码;`Limit` 在源与目标间保持一致,`Path` 和 `FilePathName` 均由后端收敛到当前租户。大对象用 `GetObjectSha256` 流式核对原对象和复制目标,公有体验路径仍须从 CDN 独立回读。历史版本目标已存在时须核对字节哈希,发现不同内容立即停止;固定根可在新版本验证后覆盖。`ListObjects` 必须分页并限制到单个应用前缀,不得把这些存储管理原子直接开放为匿名业务接口。
108
+ 固定 CDN 应用回填优先使用服务端 `CopyObject`,公有桶复制编译资产、私有桶复制源码;`Limit` 在源与目标间保持一致,`Path` 和 `FilePathName` 均由后端收敛到当前租户。大对象用 `GetObjectSha256` 流式核对原对象和复制目标,公有体验路径仍须从 CDN 独立回读。历史版本目标已存在时须核对字节哈希,发现不同内容立即停止;固定根可在新版本验证后覆盖。`ListObjects` 必须分页并限制到单个应用前缀,不得把这些存储管理原子直接开放为匿名业务接口。大型私有文本的 `GetPrivateFileText` 字符串边界及原字节/最终ZIP验签规则见[已有详细参考](references/progressive-01-公有桶-vs-私有桶.md)。
109
109
 
110
110
  MinIO SDK 7 的复制签名不匹配还可能来自带参数 MIME:SDK 对源 `Content-Type` 签名,却在 HTTP 请求中额外保留 `StringContent` 的默认 MIME。先在独立夹具核对源 MIME、重复头和真实存储返回,再升级后端复制传输修复;不能去掉 `charset`、关闭签名校验或下载后重传来伪造通过。修复后必须同时验证公私桶原始字节、精确 MIME、源元数据及源对象保留,固定入口恢复另覆盖主库权威、真实共享租约、双节点竞争和新进程重跑。取消/超时后保持原请求键,先回读目标再决定是否继续。
111
111
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  > 按需读取;本文件由 SKILL.md 的原章节无损拆分。
4
4
 
5
- <!-- microi-progressive:chunk id=v8-file-upload-005 sha256=0b4d57f32bfe913c3a2567d2e2a86f4d5ba505d60c4348ad472c117774bbfc31 -->
5
+ <!-- microi-progressive:chunk id=v8-file-upload-005 sha256=71cebd2f6946be49188c430c146b9ee923ceb0719fbda4bd3701b40152732cae -->
6
6
  ## 公有桶 vs 私有桶
7
7
 
8
8
  ### 应用商城 ZIP
@@ -42,6 +42,12 @@ var extractResult = V8.Method.ExtractZip({
42
42
  或漂移拒绝输出;ZIP 中兼容去掉 `source/` 包装目录不改变安装根的原始路径摘要。
43
43
  仍须下载原生源码 ZIP 并逐文件验签,不用对象摘要代替 ZIP 实际返回字节的独立验证。
44
44
 
45
+ 大型 UTF8 源码可复用既有 `V8.Method.GetPrivateFileText` 与
46
+ `V8.EncryptHelper.Sha256Hex/V8.Base64.StringToBase64`,避免 CLR byte[] 逐字节复制到 Jint。
47
+ 仅在字符串按 UTF8 的摘要与权威原字节摘要一致时采用,保留 BOM、换行并核对编码长度;
48
+ 二进制或有损解码仍使用原字节路径。文本原子存在却读取失败/异常时失败关闭,不换路径
49
+ 掩盖存储故障。旧宿主缺少文本或编码能力才沿用旧路径,最终同一 ZIP 的实际字节验签保持。
50
+
45
51
  ### 已提交应用的 CDN 特殊字符别名修复(强制)
46
52
 
47
53
  - 区分逻辑路径、对象键和 URL:原始 `@` 对象的 URL 可写 `%40`;字面量 `%40` 对象的 URL 需写 `%2540`。禁止在 HDFS 全局反解码对象键,禁止迁移或覆盖协议 v3 不可变编码对象、完整性标记及清单摘要。
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: v8-saas-multi-tenant
3
- description: Microi V8 SaaS 多租户指南。用于处理 OsClient、OsClientType、OsClientNetwork、租户配置、V8.OsClientModel、隔离和租户感知代码。
3
+ description: Microi V8 SaaS 多租户指南。用于处理租户隔离、主租户推广中心、按用户开通推广分享链接、匿名试用空库及 OsClient 三参数配置。
4
4
  ---
5
5
 
6
6
  > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
@@ -88,6 +88,33 @@ V8.OsClientModel.AliOssPublicDomain // 可公开的文件域名
88
88
  `microi_save_engine_code`、`microi_create_module`、`microi_run_engine` 及应用源码/流式发布工具;
89
89
  先完整回读、计划和dryRun,再按已授权范围写入。已有推广Hook采用CreateIfMissing,不覆盖。
90
90
 
91
+ #### 通过 AI + MCP 为指定用户开通推广链接
92
+
93
+ 用户说“为某个业务员创建推广链接”时,使用现有接口完成配置和签发,不创建一次性维护引擎,也不直接改推广表。先通过 `profiles` 选择用户自己的主租户连接,执行 `microi_get_status` 核对节点、主租户及 Type/Network;普通用户的主租户不固定为官方 iTdos。
94
+
95
+ 1. 用 `microi_get_engine_code` 完整读取 `platform-saas-promotion` 和 `platform-saas-public-trial`,有分页时拼齐并核对完整 SHA-256。再通过 `microi_run_engine` 执行 `{Action:'Bootstrap'}`,读取 `Actor/Users/Settings/Roles`,确认当前会话有创建权限。按准确 Account 或 Id 解析活跃推荐人;姓名重名时先澄清,禁止猜测用户 Id。管理员可以为活跃用户创建,业务员默认只为自己创建。
96
+ 2. 执行 `{Action:'Links'}`,先查该推荐人的活动。已有符合请求且启用、未过期的链接可复用,保留其他活动与业务数据。只有平台管理员的 `Actor.CanConfigure=true` 才能配置公开开通。配置缺失且用户已授权启用时,通过 `SaveSettings` 写入真实主租户前端 HTTPS 地址;不要把 API 域名、临时测试端口或别人的平台地址当成 WebBase。仅创建链接不隐含修改已经设定的开通策略。
97
+
98
+ ```javascript
99
+ // microi_run_engine:apiEngineKey='platform-saas-promotion'
100
+ // params 为下列对象;confirmExecution 使用同一 ApiEngineKey。
101
+ { Action:'SaveSettings', Enabled:true, WebBase:'https://<主租户前端域名>',
102
+ TrialDays:14, DailyLimit:20, LinkLimit:50, ManagerRoleIds:[] }
103
+ ```
104
+
105
+ 上例为未配置时的默认值。已有试用天数、每日额度、单链接额度和管理角色应从 Bootstrap 回读并保留,除非用户明确要求调整;`ManagerRoleIds` 使用真实角色 Id 数组。保存后再次 Bootstrap 核对本分区配置。
106
+ 3. 无合适活动时执行下列请求。`ReferralUserId` 必须来自第 1 步的权威用户目录;业务员额度和试用天数不能超过主租户设定值。
107
+
108
+ ```javascript
109
+ { Action:'CreateLink', Title:'<推广活动名称>', ReferralUserId:'<sys_user.Id>',
110
+ TrialDays:14, MaxTenants:50, ValidDays:30, Remark:'<可选活动说明>' }
111
+ ```
112
+
113
+ 创建超时先按推荐人、活动名称和时间回读 Links,确认是否已创建;禁止盲目重试导致重复活动。取得 `Data.Id` 后执行 `{Action:'ShareLink', Id:'<活动Id>'}`,返回 `Data.Url` 才是可分享地址。不要手拼 `ref=<用户Id>` 或将活动 Id 代替 `LinkToken`;票据绑定推荐人、活动、运行分区、到期时间和版本。切换链接启停状态会撤销旧地址,之后需重新签发。
114
+ 4. 回读 Links 核对归属、启用状态、期限、试用天数和额度。在全新、未登录的浏览器 context 打开 `Data.Url`,核对匿名 `platform-saas-public-trial` 的 Bootstrap 成功、表单与图形验证码可用。验收链接不需要实际创建客户租户;只有明确授权开库后才提交真实申请,并按同一 RequestId 回读任务、租户归属和登录地址,保留幂等及精确清理证据。
115
+
116
+ 最终交付可点击的分享地址、推荐人、试用天数、链接到期时间及额度,并区分“链接已可访问”和“客户租户已实际开通”。若接口不存在或平台版本不足,走官方 SaaS 应用与内置微服务更新,不通过临时 SQL 绕过鉴权。
117
+
91
118
  制作空数据库时,角色、账号绑定和权限快照必须作为同一初始模板处理。只保留明确声明的初始角色,按权威角色重建保留账号的 `RoleIds` 与等级;删除业务角色及孤立菜单权限,清空包含源业务菜单的角色权限快照。初始角色缺失、删除或等级不符时停止制作,不得根据账号现有角色列表、角色名称或高等级推测哪些角色应保留。
92
119
 
93
120
  组织数据属于同一空库模板边界:只保留明确声明的初始组织和部门,将保留账号的部门绑定与名称同步归一,并清理旧版账号关系表。保护这些平台表的物理结构,初始组织缺失或已删除时停止制作;验收必须在新租户查看真实组织树,不能只检查角色数量。清理只能作用于制作过程的隔离副本。